Commodore 64 Programmer's Reference Guide
Commodore 64 Programmer's Reference Guide
*********
*********
I would like to thank the following persons for their valuable help:
There was a lot of work, but finally, after five weeks of correcting
OCR-errors and formatting the text to readable format, it is ready. I
hope that this massive project shows to the C= community that it is in
a fact possible for one man to convert a 500 page book to ASCII text.
One just have to be dedicated, believe that it can be done and have
the PATIENCE for it... and lots of free time. So, who's going to etext
Inside Commodore DOS?
If you find errors in the text, please report them so that they can
be fixed. There should not be many, though...
*********
Note: To extract the ascii text basic programs all at once from this
etext use "tok64" by Cris Berneburg <[email protected]>.
*********
Now a whole page fits nicely on the screen and you can use Page Up/Page
Down keys to flip pages. Just be sure that the ~ characters are always
on the last line of the screen.
*********
COMMODORE 64
PROGRAMMER'S
REFERENCE GUIDE
Published by
Commodore Business Machines, Inc.
and
Howard W. Sams & Co., Inc.
i
~
FIRST EDITION
FOURTH PRINTING-1983
ii
~
TABLE OF CONTENTS
INTRODUCTION ....................................................... ix
o What's Included? .............................................. x
o How to Use This Reference Guide ............................... xi
o Commodore 64 Applications Guide ............................... xii
o Commodore Information Network ................................. xvii
iv
~
v
~
vi
~
vii
~~
INTRODUCTION
ix
~
WHAT'S INCLUDED?
-----------
* CP/M is a registered trademark of Digital Research, Inc.
x INTRODUCTION
~
1. BASIC keywords are shown in capital letters. They must appear where
shown in the statement, entered and spelled exactly as shown.
2. Items shown within quotation marks (" ") indicate variable data
which you must put in. Both the quotation marks and the data inside
the quotes must appear where shown in each statement.
3. Items inside the square brackets ([ ]) indicate an optional state-
ment parameter. A parameter is a limitation or additional qualifier
for your statements. If you use an optional parameter you must
supply the data for that optional parameter. In addition, ellipses
(...) show that an optional item can be repeated as many times as
a programming line allows.
4. If an item in the square brackets ([ ]) is UNDERLINED, that means
that you MUST use those certain characters in the optional para-
meters, and they also have to be spelled exactly as shown.
5. Items inside angle brackets (< >) indicate variable data which you
provide. While the slash (/) indicates that you must make a choice
between two mutually exclusive options.
OPEN <file-num>,<device>[,<address>],["<drive>:<filename>][,<mode>]"
INTRODUCTION xi
~
When you first thought about buying a computer you probably asked
yourself, "Now that I can afford to buy a computer, what can I do with
it once I get one?"
The great thing about your COMMODORE 64 is that you can make it do what
YOU want it to do! You can make it calculate and keep track of home and
business budget needs. You can use it for word processing. You can make
it play arcade-style action games. You can make it sing. You can even
create your own animated cartoons, and more. The best part of owning a
COMMODORE 64 is that even if it did only one of the things listed below
it would be well worth the price you paid for it. But the 64 is a
complete computer and it does do EVERYTHING listed and then some!
xii INTRODUCTION
~
APPLICATION COMMENTS/REQUIREMENTS
ACTION PACKED You can get real Bally Midway arcade games GAMES
like Omega Race, Gorf and Wizard of War, as well
as "play and learn" games like Math Teacher 1,
Home Babysitter and Commodore Artist.
INTRODUCTION xiii
~
-----------
* CP/M is a Registered trademark of Digital Research, Inc.
xiv INTRODUCTION
~
INTRODUCTION xv
~
SIMULATIONS Computer simulations let you conduct dangerous
or expensive experiments at minimum risk and
cost.
SPORTS DATA The Source (TM) and CompuServe (TM) both offer
sports information which you can get using
your COMMODORE 64 and a VICMODEM.
These are just a few of the many applications for you and your
COMMODORE 64. As you can see, for work or play, at home, in school
or the office, your COMMODORE 64 gives you a practical solution for
just about any need.
Commodore wants you to know that our support for users only STARTS
with your purchase of a Commodore computer. That's why we've created
two publications with Commodore information from around the world, and
a "two-way" computer information network with valuable input for users
in the U.S. and Canada from coast to coast.
In addition, we wholeheartedly encourage and support the growth of
Commodore Users' Clubs around the world. They are an excellent source
of information for every Commodore computer owner from the beginner
to the most advanced. The magazines and network, which are more fully
described below, have the most up-to-date information about how to get
involved with the Users' Club in your area.
Finally, your local Commodore dealer is a useful source of Commodore
support and information.
POWER/PLAY
The Home Computer Magazine
xvi INTRODUCTION
~
COMMODORE
The Microcomputer Magazine
INTRODUCTION xvii
~
CHAPTER 1
BASIC
PROGRAMMING
RULES
o Introduction
o Screen Display Codes (BASIC
Character Set)
o Programming Numbers and
variables
o Expressions and Operators
o Programming Techniques
1
~
INTRODUCTION
This chapter talks about how BASIC stores and manipulates data. The
topics include:
The Operating System is contained in the Read Only Memory (ROM) chips
and is a combination of three separate, but interrelated, program
modules.
1) DIRECT Mode
2) PROGRAM Mode
1) When you're using the DIRECT mode, BASIC statements don't have
line numbers in front of the statement. They are executed whenever
the <RETURN> key is pressed.
2) The PROGRAM mode is the one you use for running programs.
When using the PROGRAM mode, all of your BASIC statements must have
line numbers in front of them. You can have more than one BASIC
statement in a line of your program, but the number of statements is
limited by the fact that you can only put 80 characters on a logical
screen line. This means that if you are going to go over the 80
character limit you have to put the entire BASIC statement that
doesn't fit on a new line with a new line number.
Always type NEW and hit <RETURN> before starting a new program.
The Commodore 64 has two complete character sets that you can use
either from the keyboard or in your programs.
In SET 1, the upper case alphabet and the numbers 0-9 are available
without pressing the <SHIFT> key. If you hold down the <SHIFT> key
while typing, the graphics characters on the RIGHT side of the front of
the keys are used. If you hold down the <C=> key while typing, the
graphics characters on the LEFT side of the front of the key are used.
Holding down the <SHIFT> key while typing any character that doesn't
have graphic symbols on the front of the key gives you the symbol on the
top most part of the key.
In SET 2, the lower case alphabet and the numbers 0-9 are available
without pressing the <SHIFT> key. The upper case alphabet is available
when you hold down the <SHIFT> key while typing. Again, the graphic
symbols on the LEFT side of the front of the keys are displayed by press-
ing the <C=> key, while the symbols on the top most part of any key
without graphics characters are selected when you hold down the <SHIFT>
key while typing.
To switch from one character set to the other press the <C=> and
the <SHIFT> keys together.
Constants are the data values that you put in your BASIC statements.
BASIC uses these values to represent data during statement execution.
CBM BASIC can recognize and manipulate three types of constants:
1) INTEGER NUMBERS
2) FLOATING-POINT NUMBERS
3) STRINGS
-12
8765
-32768
+44
0
-32767
+-----------------------------------------------------------------------+
| NOTE: Do NOT put commas inside any number. For example, always type |
| 32,000 as 32000. If you put a comma in the middle of a number you |
| will get the BASIC error message ?SYNTAX ERROR. |
+-----------------------------------------------------------------------+
1) SIMPLE NUMBER
2) SCIENTIFIC NOTATION
the numbers are rounded to nine digits when results are printed. Some
examples of simple floating-point numbers are:
1.23 .7777777
-.998877 -333.
+3.1459 .01
1) THE MANTISSA
2) THE LETTER E
3) THE EXPONENT
235.988E-3 (.235988)
2359E6 (2359000000.)
-7.09E-12 (-.00000000000709)
-3.14159E+5 (-314159.)
(that is, any character spaces NOT taken up by the line number and other
required parts of the statement).
A string constant can contain blanks, letters, numbers, punctuation
and color or cursor control characters in any combination. You can even
put commas between numbers. The only character which cannot be included
in a string is the double quote mark ("). This is because the double
quote mark is used to define the beginning and end of the string.
A string can also have a null value-which means that it can contain no
character data. You can leave the ending quote mark off of a string if
it's the last item on a line or if it's followed by a colon (:). Some
examples of string constants are:
+-----------------------------------------------------------------------+
| NOTE: Us CHR$(34) to include quotes (") in strings. |
+-----------------------------------------------------------------------+
Variables are names that represent data values used in your BASIC
statements. The value represented by a variable can be assigned by
setting it equal to a constant, or it can be the result of calculations
in the program. Variable data, like constants, can be integers, floating-
point numbers, or strings. If you refer to a variable name in a program
before a value has been assigned, the BASIC Interpreter will auto-
matically create the variable with a value of zero if it's an integer or
floating-point number. Or it will create a variable with a null value if
you're using strings.
Variable names can be any length but only the first two characters are
considered significant in CBM BASIC. This means that all names used for
variables must NOT have the same first two characters. Variable names may
NOT be the same as BASIC keywords and they may NOT contain keywords in
the middle of variable names. Keywords include all BASIC commands, state-
ments, function names and logical operator names. If you accidentally use
a keyword in the middle of a variable name, the BASIC error message
?SYNTAX ERROR will show up on your screen.
The characters used to form variable names are the alphabet and the
numbers 0-9. The first character of the name must be a letter. Data
type declaration characters (%) and ($) can be used as the last char-
acter of the name. The percent sign declares the variable to be an
integer and the dollar sign ($) declares a string variable. If no type
declaration character is used the Interpreter will assume that the vari-
able is a floating-point. Some examples of variable names, value as-
signments and data types are:
1) ARITHMETIC
2) STRING
ARITHMETIC EXPRESSIONS
ARITHMETIC OPERATIONS
ADDITION (+): The plus sign (+) specifies that the operand on the
right is added to the operand on the left.
EXAMPLES:
2+2
A+B+C
X%+1
BR+10E-2
SUBTRACTION (-): The minus sign (-) specifies that the operand on the
right is subtracted from the operand on the left.
EXAMPLES:
4-1
100-64
A-B
55-142
The minus can also be used as a unary minus. That means that it is the
minus sign in front of a negative number. This is equal to subtracting
the number from zero (0).
EXAMPLES:
-5
-9E4
-B
4-(-2) same as 4+2
DIVISION (/): The slash (/) specifies that the operand on the left is
divided by the operand on the right.
EXAMPLES:
10/2
6400/4
A/B
4E2/XR
EXAMPLES:
2^2 Equivalent to: 2*2
3^3 Equivalent to: 3*3*3
4^4 Equivalent to: 4*4*4*4
AB^CD
3^-2 Equivalent to: 1/3*1/3
RELATIONAL OPERATORS
The relational operators (<, =, >, <=, >=, <>) are primarily used
to compare the values of two operands, but they also produce an arith-
metic result. The relational operators and the logical operators (AND,
OR, and NOT), when used in comparisons, actually produce an arithmetic
true/false evaluation of an expression. If the relationship stated in
the expression is true the result is assigned an integer value of - 1
and if it's false a value of 0 is assigned. These are the relational
operators:
< LESS THAN
= EQUAL TO
> GREATER THAN
<= LESS THAN OR EQUAL TO
>= GREATER THAN OR EQUAL TO
<> NOT EQUAL TO
EXAMPLES:
EXAMPLES:
Numeric data items can only be compared (or assigned) to other numeric
items. The same is true when comparing strings, otherwise the BASIC error
message ?TYPE MISMATCH will occur. Numeric operands are compared by first
converting the values of either or both operands from integer to
floating-point form, as necessary. Then the relationship of the floating-
point values is evaluated to give a true/false result.
At the end of all comparisons, you get an integer no matter what data
type the operand is (even if both are strings). Because of this,
a comparison of two operands can be used as an operand in performing
calculations. The result will be - 1 or 0 and can be used as anything but
a divisor, since division by zero is illegal.
LOGICAL OPERATORS
The logical operators (AND, OR, NOT) can be used to modify the meanings
of the relational operators or to produce an arithmetic result. Logical
operators can produce results other than -1 and 0, though any nonzero
result is considered true when testing for a true/false condition.
The logical operators (sometimes called Boolean operators) can also be
used to perform logic operations on individual binary digits (bits) in
two operands. But when you're using the NOT operator, the operation is
performed only on the single operand to the right. The operands must be
in the integer range of values (-32768 to +32767) (floating-point
numbers are converted to integers) and logical operations give an integer
result.
Logical operations are performed bit-by-corresponding-bit on the two
operands. The logical AND produces a bit result of 1 only if both operand
bits are 1. The logical OR produces a bit result of I if either operand
bit is 1. The logical NOT is the opposite value of each bit as a single
operand. In other words, it's really saying, "if it's NOT 1 then it is 0.
If it's NOT 0 then it is 1."
The exclusive OR (XOR) doesn't have a logical operator but it is per-
formed as part of the WAIT statement. Exclusive OR means that if the bits
of two operands are equal then the result is 0 otherwise the result is 1.
Logical operations are defined by groups of statements which, taken
together, constitute a Boolean "truth table" as shown in Table 1-2.
EXAMPLES:
HIERARCHY OF OPERATIONS
A+B
C^(D+E)/2
((X-C^(D+E)/2)*10)+1
GG$>HH$
JJ$+"MORE"
K%=1 AND M<>X
K%=2 OR (A=B AND M<X)
NOT (D=E)
STRING OPERATIONS
Strings are compared using the same relational operators (=, <>,
<=, >=, <, >) that are used for comparing numbers. String compari-
sons are mode by taking one character at a time (left-to-right) from
each string and evaluating each character code position from the PET/
CBM character set. If the character codes are the same, the characters
are equal. If the character codes differ, the character with the lower
code number is lower in the character set. The comparison stops when
the end of either string is reached. All other things being equal, the
shorter string is considered less than the longer string. Leading or
trailing blanks ARE significant.
Regardless of the data types, at the end of all comparisons you get
an integer result. This is true even if both operands are strings.
Because of this a comparison of two string operands can be used as an
operand in performing calculations. The result will be - 1 or 0 (true or
false) and can be used as anything but a divisor since division by zero
is illegal.
STRING EXPRESSIONS
10 A$="FILE": B$="NAME"
20 NAM$=A$+B$ (gives the string: FILENAME)
30 RES$="NEW "+A$+B$ (gives the string: NEW FILENAME)
^
| +-----------------+
+-------+ Note space here.|
+-----------------+
BASIC PROGRAMMING RULES 17
~
PROGRAMMING TECHNIQUES
DATA CONVERSIONS
Now that you know what variables are, let's take that information an
put it together with the INPUT statement for some practical program-
ming applications.
In our first example, you can think of a variable as a "storage com-
partment" where the Commodore 64 stores the user's response to your
prompt question. To write a program which asks the user to type in a
name, you might assign the variable N$ to the name typed in. Now
every time you PRINT N$ in your program, the Commodore 64 will
automatically PRINT the name that the user typed in.
Type the word NEW on your Commodore 64. Hit the <RETURN> key
and try this example:
1) NUMERIC
2) STRING
You probably remember from the earlier sections that numeric vari-
ables are used to store number values such as 1, 100, 4000, etc. A
numeric variable can be a single letter (A), any two letters (AB), a
letter and a number (AI), or two letters and a number (AB1). You can save
memory space by using shorter variables. Another helpful hint is to use
letters and numbers for different categories in the same program (AI,
A2, A3). Also, if you want whole numbers for an answer instead of
numbers with decimal points, all you have to do is put a percent sign
(%) at the end of your variable name (AB%, AI%, etc.)
Now let's look at a few examples that use different types of variables
and expressions with the INPUT statement.
+-----------------------------------------------------------------------+
| NOTE:IN can NOT = 0, and E1, E2, E3 can NOT all be 0 at the same time.|
+-----------------------------------------------------------------------+
LINE-BY-LINE EXPLANATION OF
INCOME/EXPENSE BUDGET EXAMPLE
+-----------+-----------------------------------------------------------+
| Line(s) | Description |
+-----------+-----------------------------------------------------------+
| 5 | Clears the screen. |
| 10 | PRINT/INPUT statement. |
| 20 | Inserts blank line. |
| 30 | Expense Category 1 = E1$. |
| 40 | Expense Amount = E1. |
| 50 | Inserts blank line. |
| 60 | Expense Category 2 = E2. |
| 70 | Expense Amount 2 = E2. |
| 80 | Inserts blank line. |
| 90 | Expense Category 3 = E3. |
| 100 | Expense Amount 3 = E3. |
| 110 | Clears the screen. |
| 120 | Add Expense Amounts = E. |
| 130 | Calculate Expense/income%. |
| 140 | Display Income. |
| 150 | Display Total Expenses. |
| 160 | Display Incomes - Expenses. |
| 170 | Inserts blank line. |
| 180-200 | lines 180-200 calculate % each expense |
| | amount is of total expenses. |
| 210 | Inserts blank line. |
| 220 | Display E/IN %. |
| 230 | Time delay loop. |
+-----------+-----------------------------------------------------------+
20 C=A*B
Enter these 3 lines and RUN the program. Notice that the messages are
inside the quotes while the variables are not.
Now let's say that you wanted a dollar sign ($) in front of the number
represented by variable C. The $ must be PRINTed inside quotes and in
front of variable C. To add the $ to your program hit the <RUN/STOP>
and <RESTORE> keys. Now type in line 40 as follows:
40 PRINT"$" C
10 Z$="$"
Now whenever you need a dollar sign you can use the string variable
Z$. Try this:
10 Z$="$": INPUT A
20 PRINT Z$A
line 10 defines the $ as a string variable called Z$, and then INPUTs a
number called A. line 20 PRINTs Z$ ($) next to A (number).
You'll probably find that it's easier to assign certain characters,
like dollar signs, to a string variable than to type "$" every time you
want to calculate dollars or other items which require "" like %.
USING THE GET STATEMENT
Most simple programs use the INPUT statement to get data from the
person operating the computer. When you're dealing with more complex
needs, like protection from typing errors, the GET statement gives you
more flexibility and your program more "intelligence." This section shows
you how to use the GET statement to add some special screen editing
features to your programs.
NEW
10 TI$="000000"
20 IF TI$ < "000015" THEN 20
Now type RUN, hit <RETURN> and while the program is RUNning type in the
word HELLO.
Notice that nothing happened for about IS seconds when the program
started. Only then did the message HELLO appear on the screen.
Imagine standing in line for a movie. The first person in the line is
the first to get a ticket and leave the line. The last person in line is
last for a ticket. The GET statement acts like a ticket taker. First it
looks to see if there are any characters "in line." In other words have
any keys been typed. If the answer is yes then that character gets placed
in the appropriate variable. If no key was pressed then an empty value is
assigned to a variable,
At this point it's important to note that if you try to put more than
10 characters into the buffer at one time, all those over the 10th
character will be lost.
Since the GET statement will keep going even when no character is
typed, it is often necessary to put the GET statement into a loop so that
it will have to wait until someone hits a key or until a character is
received through your program.
Below is the recommended form for the GET statement. Type NEW to erase
your previous program.
Notice that there is NO SPACE between the quote marks("") on this line.
This indicates an empty value and sends the program back to the GET
statement in a continuous loop until someone hits a key on the computer.
Once a key is hit the program will continue with the line following line
10. Add this line to your program:
Now RUN the program. Notice that no cursor appears on the screen, but
any character you type will be printed in the screen. This 2-line program
can be turned into part of a screen editor program as shown below.
There are many things you can do with a screen editor. You can have
a flashing cursor. You can keep certain keys like <CLR/HOME> from
accidentally erasing the whole screen. You might even want to be able to
use your function keys to represent whole words or phrases. And speaking
of function keys, the following program lines give each function key a
special purpose. Remember this is only the beginning of a program that
you can customize for your needs.
The CHR$ numbers in parentheses come from the CHR$ code chart in
Appendix C. The chart lists a different number for each character. The
four function keys are set up to perform the tasks represented by the
instructions that follow the word THEN in each line. By changing the
CHR$ number inside each set of parentheses you can designate different
keys. Different instructions would be performed if you changed the
information after the THEN statement.
You can pack more instructions - and power - into your BASIC programs by
making each program as short as possible. This process of shortening
programs is called "crunching."
Crunching programs lets you squeeze the maximum possible number of
instructions into your program. It also helps you reduce the size of
programs which might not otherwise run in a given size; and if you're
writing a program which requires the input of data such as inventory
items, numbers or text, a short program will leave more memory space free
to hold data.
ABBREVIATING KEYWORDS
the question mark (?) which is the BASIC abbreviation for the PRINT
command. However, if you LIST a program that has abbreviations, the
Commodore 64 will automatically print out the listing with the full-
length keywords. If any program line exceeds 80 characters (2 lines on
the screen) with the keywords unabbreviated, and you want to change it,
you will have to re-enter that line with the abbreviations before saving
the program. SAVEing a program incorporates the keywords without
inflating any lines because BASIC keywords are tokenized by the Commodore
64. Usually, abbreviations are added after a program is written and it
isn't going to be LISTed any more before SAVEing.
Most programmers start their programs at line 100 and number each fine
at intervals of 10 (i.e., 100, 110, 120). This allows extra lines of
instruction to be added (111, 112, etc.) as the program is developed.
One means of crunching the program after it is completed is to change
the fine numbers to the lowest numbers possible (i.e., 1, 2, 3) because
longer line numbers take more memory than shorter numbers when referenced
by GOTO and GOSUB statements. For instance, the number 100 uses 3 bytes
of memory (one for each number) while the number I uses only 1 byte.
You can put more than one instruction on each numbered line in your
program by separating them by a colon. The only limitation is that all
the instructions on each line, including colons, should not exceed the
standard 80-character line length. Here is an example of two programs,
before and after crunching:
won't need those REM statements anymore and you can save quite a bit of
space by removing the REM statements. If you plan to revise or study the
program structure in the future, it's a good idea to keep a copy on file
with the REM statements intact.
USING VARIABLES
Arrays and matrices are similar to DATA statements in that long amounts
of data can be handled as a list, with the data handling portion of the
program drawing from that list, in sequence. Arrays differ in that the
list can be multi-dimensional
ELIMINATING SPACES
programs to provide clarity, you actually don't need any spaces in your
program and will save space if you eliminate them.
CHAPTER 2
BASIC LANGUAGE
VOCABULARY
o Introduction
o BASIC Keywords, Abbreviations,
and Function Types
o Description of BASIC Keywords
(Alphabetical)
o The Commodore 64 Keyboard and
Features
o Screen Editor
~
INTRODUCTION
This chapter explains CBM BASIC Language keywords. First we give you an
easy to read list of keywords, their abbreviations and what each letter
looks like on the screen. Then we explain how the syntax and operation of
each keyword works in detail, and examples are shown to give you an idea
as to how to use them in your programs.
As a convenience, Commodore 64 BASIC allows you to abbreviate most
keywords. Abbreviations are entered by typing enough letters of the
keyword to distinguish it from all other keywords, with the last letter
or graphics entered holding down the <SHIFT> key.
Abbreviations do NOT save any memory when they're used in programs,
because all keywords are reduced to single-character "tokens" by the
BASIC Interpreter. When a program containing abbreviations is listed, all
keywords appear in their fully spelled form. You can use abbreviations to
put more statements onto a program line even if they won't fit onto the
80-character logical screen line. The Screen Editor works on an 80-
character line. This means that if you use abbreviations on any line that
goes over 80 characters, you will NOT be able to edit that line when
LISTed. Instead, what you'll have to do is (1) retype the entire line
including all abbreviations, or (2) break the single line of code into
two lines, each with its own line number, etc.
A complete list of keywords, abbreviations, and their appearance on the
screen is presented in Table 2-1. They are followed by an alphabetical
description of all the statements, commands, and functions available on
your Commodore 64.
This chapter also explains the BASIC functions built into the BASIC
Language Interpreter. Built-in functions can be used in direct mode
statements or in any program, without having to define the function
further. This is NOT the case with user-defined functions. The results of
built-in BASIC functions can be used as immediate output or they can be
assigned to a variable name of an appropriate type. There are two types
of BASIC functions:
1) NUMERIC
2) STRING
+-----------+----------------------+----------------+-------------------+
| COMMAND | ABBREVIATION | SCREEN | FUNCTION TYPE |
+-----------+----------------------+----------------+-------------------+
| | | | |
| END | E <SHIFT+N> | | |
| | | | |
| EXP | E <SHIFT+X> | | NUMERIC |
| | | | |
| FN | none | FN | |
| | | | |
| FOR | F <SHIFT+O> | | |
| | | | |
| FRE | F <SHIFT+R> | | NUMERIC |
| | | | |
| GET# | none | GET# | |
| | | | |
| GOSUB | GO <SHIFT+S> | | |
| | | | |
| GOTO | G <SHIFT+O> | | |
| | | | |
| IF | none | IF | |
| | | | |
| INPUT | none | INPUT | |
| | | | |
| INPUT# | I <SHIFT+N> | | |
| | | | |
| INT | none | INT | NUMERIC |
| | | | |
| LEFT$ | LE <SHIFT+F> | | STRING |
| | | | |
| LEN | none | LEN | NUMERIC |
| | | | |
| LET | L <SHIFT+E> | | |
| | | | |
| LIST | L <SHIFT+I> | | |
| | | | |
| LOAD | L <SHIFT+O> | | |
| | | | |
| LOG | none | LOG | NUMERIC |
+-----------+----------------------+----------------+-------------------+
| COMMAND | ABBREVIATION | SCREEN | FUNCTION TYPE |
+-----------+----------------------+----------------+-------------------+
| | | | |
| MID$ | M <SHIFT+I> | | STRING |
| | | | |
| NEW | none | NEW | |
| | | | |
| NEXT | N <SHIFT+E> | | |
| | | | |
| NOT | N <SHIFT+O> | | |
| | | | |
| ON | none | ON | |
| | | | |
| OPEN | O <SHIFT+P> | | |
| | | | |
| OR | none | OR | |
| | | | |
| PEEK | P <SHIFT+E> | | NUMERIC |
| | | | |
| POKE | P <SHIFT+O> | | |
| | | | |
| POS | none | POS | NUMERIC |
| | | | |
| PRINT | ? | ? | |
| | | | |
| PRINT# | P <SHIFT+R> | | |
| | | | |
| READ | R <SHIFT+E> | | |
| | | | |
| REM | none | REM | |
| | | | |
| RESTORE| RE <SHIFT+S> | | |
| | | | |
| RETURN | RE <SHIFT+T> | | |
| | | | |
| RIGHT$ | R <SHIFT+I> | | STRING |
| | | | |
| RND | R <SHIFT+N> | | NUMERIC |
| | | | |
| RUN | R <SHIFT+U> | | |
| | | | |
| SAVE | S <SHIFT+A> | | |
| | | | |
| SGN | S <SHIFT+G> | | NUMERIC |
| | | | |
| SIN | S <SHIFT+I> | | NUMERIC |
| | | | |
| SPC( | S <SHIFT+P> | | SPECIAL |
| | | | |
| SQR | S <SHIFT+Q> | | NUMERIC |
| | | | |
| STATUS | ST | ST | NUMERIC |
| | | | |
| STEP | ST <SHIFT+E> | | |
| | | | |
| STOP | S <SHIFT+T> | | |
| | | | |
| STR$ | ST <SHIFT+R> | | STRING |
| | | | |
| SYS | S <SHIFT+Y> | | |
| | | | |
| TAB( | T <SHIFT+A> | | SPECIAL |
| | | | |
| TAN | none | TAN | NUMERIC |
| | | | |
| THEN | T <SHIFT+H> | | |
| | | | |
| TIME | TI | TI | NUMERIC |
| | | | |
| TIME$ | TI$ | TI$ | STRING |
| | | | |
| TO | none | TO | |
| | | | |
| USR | U <SHIFT+S> | | NUMERIC |
| | | | |
| VAL | V <SHIFT+A> | | NUMERIC |
| | | | |
| VERIFY | V <SHIFT+E> | | |
| | | | |
| WAIT | W <SHIFT+A> | | |
+-----------+----------------------+----------------+-------------------+
ABS
TYPE: Function-Numeric
FORMAT: ABS(<expression>)
Action: Returns the absolute value of the number, which is its value
without any signs. The absolute value of a negative number is that
number multiplied by -1.
10 X = ABS (Y)
10 PRINT ABS (X*J)
10 IF X = ABS (X) THEN PRINT"POSITIVE"
AND
TYPE: Operator
FORMAT: <expression> AND <expression>
0 1 0 1
AND 0 AND 0 AND 1 AND 1
------ ----- ----- -----
0 0 0 1
converted to binary format, the range allowed yields 16 bits for each
number. Corresponding bits are ANDed together, forming a 16-bit result
in the same range.
17
AND 194
--------
0000000000010001
AND 0000000011000010
--------------------------
(BINARY) 0000000000000000
--------------------------
(DECIMAL) 0
32007
AND 28761
----------
0111110100000111
AND 0111000001011001
--------------------------
(BINARY) 0111000000000001
--------------------------
(DECIMAL) 28673
-241
AND 15359
----------
1111111100001111
AND 0011101111111111
--------------------------
(BINARY) 0011101100001111
--------------------------
(DECIMAL) 15119
50 IF X=7 AND W=3 THEN GOTO 10: REM ONLY TRUE IF BOTH X=7
AND W=3 ARE TRUE
60 IF A AND Q=7 THEN GOTO 10: REM TRUE IF A IS NON-ZERO
AND Q=7 IS TRUE
ASC
TYPE: Function-Numeric
FORMAT: ASC(<string>)
10 PRINT ASC("Z")
20 X = ASC("ZEBRA")
30 J = ASC(J$)
30 J = ASC(J$ + CHR$(0))
ATN
TYPE: Function-Numeric
FORMAT: ATN(<number>)
10 PRINT ATN(0)
20 X = ATN(J)*180/ {pi} : REM CONVERT TO DEGREES
CHR$
TYPE: Function-String
FORMAT: CHR$ (<number>)
CLOSE
Action: This statement shuts off any data file or channel to a device.
The file number is the same as when the file or device was OPENed (see
OPEN statement and the section on INPUT/OUTPUT programming).
When working with storage devices like cassette tape and disks, the
CLOSE operation stores any incomplete buffers to the device. When this
is not performed, the file will be incomplete on the tape and unreadable
on the disk. The CLOSE operation isn't as necessary with other devices,
but it does free up memory for other files. See your external device
manual for more details.
10 CLOSE 1
20 CLOSE X
30 CLOSE 9*(1+J)
CLR
TYPE: Statement
FORMAT: CLR
Action: This statement makes available RAM memory that had been used
but is no longer needed. Any BASIC program in memory is untouched, but
all variables, arrays, GOSUB addresses, FOR...NEXT loops, user-defined
functions, and files are erased from memory, and their space is mode
available to new variables, etc.
BASIC LANGUAGE VOCABULARY 39
~
In the case of files to the disk and cassette tape, they are not
properly CLOSED by the CLR statement. The information about the files is
lost to the computer, including any incomplete buffers. The disk drive
will still think the file is OPEN. See the CLOSE statement for more
information on this.
10 X=25
20 CLR
30 PRINT X
RUN
0
READY
CMD
Action: This statement switches the primary- output device from the TV
screen to the file specified. This file could be on disk, tape, printer,
or an I/O device like the modem. The file number must be specified in a
prior OPEN statement. The string, when specified, is sent to the file.
This is handy for titling printouts, etc.
When this command is in effect, any PRINT statements and LIST commands
will not display on the screen, but will send the text in the same
format to the file.
To re-direct the output back to the screen, the PRINT# command should
send a blank line to the CMD device before CLOSEing, so it will
stop expecting data (called "un-listening" the device).
CONT
TYPE: Command
FORMAT: CONT
10 PI=0:C=1
20 PI=PI+4/C-4/(C+2)
30 PRINT PI
40 C=C+4:GOTO 20
This program calculates the value of PI. RUN this program, and after
a short while hit the <RUN/STOP> key. You will see the display:
+----------------------------------+
BREAK IN 20 | NOTE: Might be different number. |
+----------------------------------+
Type the command PRINT C to see how far the Commodore 64 has gotten.
Then use CONT to resume from where the Commodore 64 left off.
COS
TYPE: Function
FORMAT: COS (<number>)
10 PRINT COS(0)
20 X = COS(Y* {pi} /180) : REM CONVERT DEGREES TO RADIANS
DATA
TYPE: Statement
FORMAT: DATA <list of constants>
Any characters can be included as data, but if certain ones are used
the data item must be enclosed by quote marks (" "). These include
punctuation like comma (,), colon (:), blank spaces, and shifted letters,
graphics, and cursor control characters.
10 DATA 1,10,5,8
20 DATA JOHN,PAUL,GEORGE,RINGO
30 DATA "DEAR MARY, HOW ARE YOU, LOVE, BILL"
40 DATA -1.7E-9, 3.33
DEF FN
TYPE: Statement
FORMAT: DEF FN <name> ( <variable> ) = <expression>
10 DEF FN A(X)=X+7
20 DEF FN AA(X)=Y*Z
30 DEF FN A9(Q) = INT(RND(1)*Q+1)
The function is called later in the program by using the function name
with a variable in parentheses. This function name is used like any other
variable, and its value is automatically calculated,
EXAMPLES of FN Use:
40 PRINT FN A(9)
50 R=FN AA(9)
60 G=G+FN A9(10)
In line 50 above, the number 9 inside the parentheses does not affect
the outcome of the function, because the function definition in line 20
doesn't use the variable in the parentheses. The result is Y times Z,
regardless of the value of X. In the other two functions, the value in
parentheses does affect the result.
DIM
TYPE: Statement
FORMAT: DIM <variable> ( <subscripts> )[
<variable> ( <subscripts> )...]
10 DIM A(100)
20 DIM Z (5,7), Y(3,4,5)
30 DIM Y7%(Q)
40 DIM PH$(1000)
50 F(4)=9 : REM AUTOMATICALLY PERFORMS DIM F(10)
END
TYPE: Statement
FORMAT: END
EXP
TYPE: Function-Numeric
FORMAT: EXP ( <number> )
FN
TYPE: Function-Numeric
FORMAT: FN <name> ( <number> )
PRINT FN A(Q)
1100 J = FN J(7)+ FN J(9)
9990 IF FN B7 (1+1)= 6 THEN END
TYPE: Statement
FORMAT: FOR <variable> = <start> TO <limit> [ STEP <increment> ]
Action: This is a special BASIC statement that lets you easily use a
variable as a counter. You must specify certain parameters: the
floating-point variable name, its starting value, the limit of the count,
and how much to add during each cycle.
100 L = 1
110 PRINT L
120 L = 1 + 1
130 IF L <= 10 THEN 110
140 END
100 FOR L = 1 TO 10
110 PRINT L
120 NEXT L
130 END
As you can see, the program is shorter and easier to understand using
the FOR statement.
When the FOR statement is executed, several operations take place.
The <start> value is placed in the <variable> being used in the
counter. In the example above, a I is placed in L.
When the NEXT statement is reached, the <increment> value is added to
the <variable>. If a STEP was not included, the <increment> is set to
+ 1. The first time the program above hits line 120, 1 is added to L,
so the new value of L is 2.
Now the value in the <variable> is compared to the <limit>. If the
<limit> has not been reached yet, the program G0es TO the line after
the original FOR statement. In this case, the value of 2 in L is less
than the limit of 10, so it GOes TO line 110.
Eventually, the value of <limit> is exceeded by the <variable>. At
that time, the loop is concluded and the program continues with the line
following the NEXT statement. In our example, the value of L reaches
11, which exceeds the limit of 10, and the program goes on with line
130.
When the value of <increment> is positive, the <variable> must
exceed the <limit>, and when it is negative it must become less than
the <limit>.
+---------------------------------------------+
| NOTE: A loop always executes at least once. |
+---------------------------------------------+
EXAMPLES of FOR...TO...STEP...Statement:
FRE
TYPE: Function
FORMAT: FRE ( <variable> )
Action: This function tells you how much RAM is available for your
program and its variables. If a program tries to use more space than is
available, the OUT OF MEMORY error results.
The number in parentheses can have any value, and it is not used in
the calculation.
+-----------------------------------------------------------------------+
| NOTE: If the result of FRE is negative, add 65536 to the FRE number |
| get the number of bytes available in memory. |
+-----------------------------------------------------------------------+
PRINT FRE(0)
10 X = (FRE(K)-1000)/7
950 IF FRE(0)< 100 THEN PRINT "NOT ENOUGH ROOM"
+-----------------------------------------------------------------------+
| NOTE: The following always tells you the current available RAM: |
| PRINT FRE(0) - (FRE(0) < 0)* 65536 |
+-----------------------------------------------------------------------+
GET
TYPE: Statement
FORMAT: GET <variable list>
Action: This statement reads each key typed by the user. As the user is
typing, the characters are stored in the Commodore 64's keyboard buffer.
Up to 10 characters are stored here, and any keys struck after the 10th
are lost. Reading one of the characters with the GET statement makes room
for another character.
If the GET statement specifies numeric data, and the user types a key
other than a number, the message ?SYNTAX ERROR appears. To be safe, read
the keys as strings and convert them to numbers later.
The GET statement can be used to avoid some of the limitations of the
INPUT statement. For more on this, see the section on Using the GET
Statement in the Programming Techniques section.
10 GET A$: IF A$ ="" THEN 10: REM LOOPS IN 10 UNTIL ANY KEY HIT
20 GET A$, B$, C$, D$, E$: REM READS 5 KEYS
30 GET A, A$
GET#
5 GET#1, A$
10 OPEN 1,3: GET#1, Z7$
20 GET#1, A, B, C$, D$
50 BASIC LANGUAGE VOCABULARY
~
GOSUB
TYPE: Statement
FORMAT: GOSUB <line number>
Each time the program executes a GOSUB, the line number and position
in the program line are saved in a special area called the "stack,"
which takes up 256 bytes of your memory. This limits the amount of data
that can be stored in the stack. Therefore, the number of subroutine
return addresses that can be stored is limited, and care should be taken
to make sure every GOSUB hits the corresponding RETURN, or else you'll
run out of memory even though you have plenty of bytes free.
GOTO
TYPE: Statement
FORMAT :GOTO <line number>
or GO TO <line number>
Action: This statement allows the BASIC program to execute lines out
of numerical order. The word GOTO followed by a number will make the
program jump to the line with that number. GOTO NOT followed by a number
equals GOTO 0. It must have the line number after the word GOTO.
It is possible to create loops with GOTO that will never end. The
simplest example of this is a line that GOes TO itself, like 10 GOTO 10.
These loops can be stopped using the <RUN/STOP> key on the keyboard.
GOTO 100
10 GO TO 50
20 GOTO 999
IF...THEN...
TYPE: Statement
FORMAT: IF <expression> THEN <line number>
IF <expression> GOTO <line number>
IF <expression> THEN <statements>
Action: This is the statement that gives BASIC most of its "intelli-
gence," the ability to evaluate conditions and take different actions de-
pending on the outcome.
EXAMPLE of IF...GOTO...Statement:
This program prints out the square root of any positive number. The IF
statement here is used to validate the result of the INPUT. When the
result of N <= 0 is true, the program skips to line 200, and when the
result is false the next line to be executed is 120. Note that THEN GOTO
is not needed with IF...THEN, as in line 110 where GOTO 200 actually
means THEN GOTO 200.
EXAMPLE OF IF...THEN...Statement:
The IF in line 110 tests a random number to see if it is less than .5.
When the result is true, the whole series of statements following the
word THEN are executed: first X is incremented by 1, then the program
skips to line 130. When the result is false, the program drops to the
next statement, line 120.
INPUT
TYPE: Statement
FORMAT: INPUT [ "<prompt>" ; ] <variable list>
Action: This is a statement that lets the person RUNning the program
"feed" information into the computer. When executed, this statement
PRINTs a question mark (?) on the screen, and positions the cursor 1
space to the right of the question mark. Now the computer waits, cursor
blinking, for the operator to type in the answer and press the <RETURN>
key.
The word INPUT may be followed by any text contained in quote marks
(""). This text is PRINTed on the screen, followed by the question mark.
After the text comes a semicolon (;) and the name of one or more
variables separated by commas. This variable is where the computer
stores the information that the operator types. The variable can be any
legal variable name, and you can have several different variable
names, each for a different input.
100 INPUT A
110 INPUT B, C, D
120 INPUT "PROMPT"; E
When this program RUNs, the question mark appears to prompt the
operator that the Commodore 64 is expecting an input for line 100. Any
number typed in goes into A, for later use in the program. If the answer
typed was not a number, the ?REDO FROM START message appears, which means
that a string was received when a number was expected.
If the operator just hits <RETURN> without typing anything, the vari-
able's value doesn't change.
Now the next question mark, for line 110, appears. If we type only
one number and hit the <RETURN>, Commodore 64 will now display 2
question marks (??), which means that more input is required. You can
just type as many inputs as you need separated by commas, which prevents
the double question mark from appearing. If you type more data than the
INPUT statement requested, the ?EXTRA IGNORED message appears, which
means that the extra items you typed were not put into any variables.
Line 120 displays the word PROMPT before the question mark appears. The
semicolon is required between the prompt and any list of variables.
The INPUT statement can never be used outside a program. The Commodore
64 needs space for a buffer for the INPUT variables, the same space that
is used for commands.
INPUT#
Action: This is usually the fastest and easiest way to retrieve data
stored in a file on disk or tape. The data is in the form of whole vari-
ables of up to 80 characters in length, as opposed to the one-at-a-time
method of GET#. First, the file must have been OPENed, then INPUT# can
fill the variables.
The INPUT# command assumes a variable is finished when it reads a
RETURN code (CHR$ (13)), a comma (,), semicolon (;), or colon (:).
Quote marks can be used to enclose these characters when writing if
they are needed (see PRINT# statement).
If the variable type used is numeric, and non-numeric characters are
received, a BAD DATA error results. INPUT# can read strings up to 80
characters long, beyond which a STRING TOO LONG error results.
When used with device #3 (the screen), this statement will read an
entire logical line and move the cursor down to the next line.
10 INPUT#1,A
20 INPUT#2,A$,B$
BASIC LANGUAGE VOCABULARY 55
~
INT
99 -13
LEFT$
10 A$ = "COMMODORE COMPUTERS"
20 B$ = LEFT$(A$,9): PRINT B$
RUN
COMMODORE
18
LET
TYPE: Statement
FORMAT: [LET] <variable> = <expression>
LIST
TYPE: Command
FORMAT: LIST [[<first-line>]-[<last-line>]]
Action: The LIST command allows you to look at lines of the BASIC
program currently in the memory of your Commodore 64. This lets you use
your computer's powerful screen editor, to edit programs which you've
LISTed both quickly and easily.
The LIST system command displays all or part of the program that is
currently in memory on the default output device. The LIST will normally
be directed to the screen and the CMD statement can be used to switch
output to an external device such as a printer or a disk. The LIST com-
mand can appear in a program, but BASIC always returns to the system
READY message after a LIST is executed.
When you bring the program LIST onto the screen, the "scrolling" of
the display from the bottom of the screen to the top can be slowed by
holding down the ConTRoL <CTRL> key. LIST is aborted by typing the
<RUN/STOP> key.
If no line-numbers are given the entire program is listed. If only the
first-line number is specified, and followed by a hyphen (-), that line
and all higher-numbered lines are listed. If only the last line-number is
specified, and it is preceded by a hyphen, then all lines from the
beginning of the program through that line are listed. If both numbers
are specified, the entire range, including the line-numbers LISTed, is
displayed.
LIST -1000 (Lists all lines from the lowest through 1000.)
LOAD
TYPE: Command
FORMAT: LOAD["<file-name>"][,<device>][,<address>]
Action: The LOAD statement reads the contents of a program file from
tape or disk into memory. That way you can use the information LOADed
or change the information in some way. The device number is optional,
but when it is left out the computer will automatically default to 1, the
cassette unit. The disk unit is normally device number 8. The LOAD closes
all open files and, if it is used in direct mode, it performs a CLR
(clear) before reading the program. If LOAD is executed from within a
program, the program is RUN. This means that you can use LOAD to "chain"
several programs together. None of the variables are cleared during a
chain operation.
If you are using file-name pattern matching, the first file which
matches the pattern is loaded. The asterisk in quotes by itself ("*")
causes the first file-name in the disk directory to be loaded. if the
filename used does not exist or if it is not a program file, the BASIC
error message ?FILE NOT FOUND occurs.
When LOADing programs from tape, the <file-name> can be left out, and
the next program file on the tape will be read. The Commodore 64 will
blank the screen to the border color after the PLAY key is pressed. When
the program is found, the screen clears to the background color and the
"FOUND" message is displayed. When the <C=> key, <CTRL> key, <ARROW LEFT>
key, or <SPACE BAR> is pressed, the file will be loaded. Programs will
LOAD starting at memory location 2048 unless a secondary <address> of 1
is used. If you use the secondary address of 1 this will cause the
program to LOAD to the memory location from which it was saved.
LOG
25 PRINT LOG(45/7)
1.86075234
MID$
10 A$="GOOD"
20 B$="MORNING EVENING AFTERNOON"
30 PRINT A$ + MID$(B$,8,8)
GOOD EVENING
NEW
TYPE: Command
FORMAT: NEW
+-----------------------------------------------------------------------+
| BE CAREFUL: Not clearing out an old program before typing a new one |
| can result in a confusing mix of the two programs. |
+-----------------------------------------------------------------------+
NEXT
TYPE: Statement
FORMAT: NEXT[<counter>][,<counter>]...
Action: The NEXT statement is used with FOR to establish the end of a
FOR...NEXT loop. The NEXT need not be physically the last statement
in the loop, but it is always the last statement executed in a loop. The
<counter> is the loop index's variable name used with FOR to start the
loop. A single NEXT can stop several nested loops when it is followed by
each FOR's <counter> variable name(s). To do this each name must appear
in the order of inner-most nested loop first, to outer-most nested loop
last. When using a single NEXT to increment and stop several variable
names, each variable name must be separated by commas. Loops can be
nested to 9 levels. If the counter variable(s) are omitted, the counter
associated with the FOR of the current level (of the nested loops) is
incremented.
10 FOR A=1 TO 10
20 FOR B=1 TO 20
30 NEXT
40 NEXT (Notice that no variable names are needed)
NOT
Action: The NOT logical operator "complements" the value of each bit
in its single operand, producing an integer "twos-complement" result. In
other words, the NOT is really saying, "if it isn't. When working with a
floating-point number, the operands are converted to integers and any
fractions are lost. The NOT operator can also be used in a comparison to
reverse the true/false value which was the result of a relationship test
and therefore it will reverse the meaning of the comparison. In the first
example below, if the "twos-complement" of "AA" is equal to "BB" and if
"BB" is NOT equal to "CC" then the expression is true.
+-----------------------------------------------------------------------+
| NOTE: TO find the value of NOT use the expression X=(-(X+1)). (The |
| two's complement of any integer is the bit complement plus one.) |
+-----------------------------------------------------------------------+
ON
TYPE: Statement
FORMAT: ON <variable> GOTO / GOSUB <line-number>[,<line-number>]...
Action: The ON statement is used to GOTO one of several given line-
numbers, depending upon the value of a variable. The value of the
variables can range from zero through the number of lines given. if the
value is a non-integer, the fractional portion is left off. For example,
if the variable value is 3, ON will GOTO the third line-number in the
list.
If the value of the variable is negative, the BASIC error message
?ILLEGAL QUANTITY occurs. If the number is zero, or greater than the
number of items in the list, the program just "ignores" the statement and
continues with the statement following the ON statement.
ON is really an underused variant of the IF...THEN...statement. Instead
of using a whole lot of IF statements each of which sends the program to
1 specific line, 1 ON statement can replace a list of IF statements. When
you look at the first example you should notice that the 1 ON statement
replaces 4 IF...THEN... statements.
EXAMPLES of ON Statement:
ON -(A=7)-2*(A=3)-3*(A<3)-4*(A>7)GOTO 400,900,1000,100
ON X GOTO 100,130,180,220
ON X+3 GOSUB 9000,20,9000
100 ON NUM GOTO 150,300,320,390
500 ON SUM/2 + 1 GOSUB 50,80,20
OPEN
The <file-num> is the logical file number, which relates the OPEN,
CLOSE, CMD, GET#, INPUT#, and PRINT# statements to each other and
associates them with the file-name and the piece of equipment being used.
The logical file number can range from 1 to 255 and you can assign it any
number you want in that range.
+-----------------------------------------------------------------------+
| NOTE: File numbers over 128 were really designed for other uses so |
| it's good practice to use only numbers below 127 for file numbers. |
+-----------------------------------------------------------------------+
A secondary address value of one (1) OPENs cassette tape files for
writing. A secondary address value of two (2) causes an end-of-tape
marker to be written when the file is later closed. The end-of-tape
marker prevents accidentally reading past the end of data which results
in the BASIC error message ?DEVICE NOT PRESENT.
For disk files, the secondary addresses 2 thru 14 are available for
data-files, but other numbers have special meanings in DOS commands.
You must use a secondary address when using your disk drive(s). (See
your disk drive manual for DOS command details.)
The <file-name> is a string of 1-16 characters and is optional for
cassette or printer files. If the file <type> is left out the type of
file will automatically default to the Program file unless the <mode> is
given.
Sequential files are OPENed for reading <mode>=R unless you specify that
files should be OPENed for writing <mode> =W is specified. A file <type>
can be used to OPEN an existing Relative file. Use REL for <type> with
Relative files. Relative and Sequential files are for disk only.
If you try to access a file before it is OPENed the BASIC error message
?FILE NOT OPEN will occur. If you try to OPEN a file for reading which
does not exist the BASIC error message ?FILE NOT FOUND will occur. If
a file is OPENed to disk for writing and the file-name already exists,
the DOS error message FILE EXISTS occurs. There is no check of this type
available for tape files, so be sure that the tape is properly positioned
or you might accidentally write over some data that had previously been
SAVED. If a file is OPENed that is already OPEN, the BASIC error message
FILE OPEN occurs. (See Printer Manual for further details.)
66 BASIC LANGUAGE VOCABULARY
~
OR
EXAMPLES of OR Operator:
230 KK%=64 OR 32: PRINT KK% (You typed this with a bit
value of 1000000 for 64
and 100000 for 32)
PEEK
TYPE: Statement
FORMAT: POKE <location>,<value>
POS
PRINT
TYPE: Statement
FORMAT: PRINT [<variable>][<,/;><variable>]...
1)
5 X = 5
10 PRINT -5*X,X-5,X+5,X^5
-25 0 10 3125
2)
5 X=9
10 PRINT X;"SQUARED IS";X*X;"AND";
20 PRINT X "CUBED IS" X^3
3)
90 AA$="ALPHA":BB$="BAKER":CC$="CHARLIE":DD$="DOG":EE$="ECHO"
100 PRINT AA$BB$;CC$ DD$,EE$
ALPHABAKERCHARLIEDOG ECHO
Quote Mode
Once the quote mark <SHIFT+2> is typed, the cursor controls stop
operating and start displaying reversed characters which actually stand
for the cursor control you are hitting. This allows you to program these
cursor controls, because once the text inside the quotes is PRINTed they
perform their functions. The <INST/DEL> key is the only cursor control
not affected by "quote mode."
1. Cursor Movement
KEY APPEARS AS
<CLR/HOME>
<SHIFT+CLR/HOME>
<CRSR UP/DOWN>
<SHIFT+CRSR UP/DOWN>
<CRSR LEFT/RIGHT>
<SHIFT+CRSR LEFT/RIGHT>
If you wanted the word HELLO to PRINT diagonally from the upper left
corner of the screen, you would type:
PRINT"<HOME>H<DOWN>E<DOWN>L<DOWN>L<DOWN>O"
2. Reverse Characters
Holding down the <CTRL> key and hitting <9> will cause <R> to appear
inside the quotes. This will make all characters start printing in
reverse video (like a negative of a picture). To end the reverse printing
hit <CTRL+0>, or else PRINT a <RETURN> (CHR$(13)). (Just ending the PRINT
statement without a semicolon or comma will take care of this.)
3.Color Controls
Holding down the <CTRL> key or <C=> key with any of the 8 color keys
will make a special reversed character appear in the quotes. When the
character is PRINTed, then the color change will occur.
If you wanted to PRINT the word HELLO in cyan and the word THERE
in white, type:
4. Insert Mode
The spaces created by using the <INST/DEL> key have some of the same
characteristics as quote mode. The cursor controls and color controls
show up as reversed characters. The only difference is in the <INST> and
<DEL>, which performs its normal function even in quote mode, now
creates the <T>. And <INST>, which created a special character in quote
mode, inserts spaces normally.
Because of this, it is possible to create a PRINT statement containing
DELetes, which cannot be PRINTed in quote mode. Here is an example
of how this is done:
10 PRINT"HELLO"<DEL><INST><INST><DEL><DEL>P"
When the above line is RUN, the word displayed will be HELP, because
the last two letters are deleted and the P is put in their place.
+-----------------------------------------------------------------------+
| WARNING: The DELetes will work when LISTing as well as PRINTing, so |
| editing a line with these characters will be difficult. |
+-----------------------------------------------------------------------+
There are some other characters that can be PRINTed for special
functions, although they are not easily available from the keyboard. In
order to get these into quotes, you must leave empty spaces for them in
the line, hit <RETURN> or <SHIFT+RETURN>, and go back to the spaces with
the cursor controls. Now you must hit <RVS ON>, to start typing reversed
characters, and type the keys shown below:
<SHIFT+RETURN> <SHIFT+M>
switch to lower case <N>
switch to upper case <SHIFT+N>
disable case-switching keys <H>
enable case-switching keys <I>
PRINT#
1)
2)
10 CO$=CHR$(44):CR$=CHR$(13)
20 PRINT#1,"AAA"CO$"BBB", AAA,BBB CCCDDDEEE
"CCC";"DDD";"EEE"CR$ (carriage return)
"FFF"CR$; FFF(carriage return)
30 INPUT#1,A$,BCDE$,F$
3)
5 CR$=CHR$(13)
10 PRINT#2,"AAA";CR$;"BBB" (10 blanks) AAA
20 PRINT#2,"CCC"; BBB
(10 blanks)CCC
30 INPUT#2,A$,B$,DUMMY$,C$
READ
TYPE: Statement
FORMAT: READ <variable>[,<variable>]...
Action: The READ statement is used to fill variable names from con-
stants in DATA statements. The data actually read must agree with the
variable types specified or the BASIC error message ?SYNTAX ERROR will
result.(*) Variables in the DATA input-list must be separated by commas.
A single READ statement can access one or more DATA statements,
which will be accessed in order (see DATA), or several READ statements
can access the same DATA statement. If more READ statements are executed
than the number of elements in DATA statements(s) in the program, the
+-----------------------------------------------------------------------+
| *NOTE: The ?SYNTAX ERROR will appear with the line number from the |
| DATA statement, NOT the READ statement. |
+-----------------------------------------------------------------------+
1 READ CITY$,STATE$,ZIP
5 DATA DENVER,COLORADO, 80211
REM
TYPE: Statement
FORMAT: REM [<remark>]
RESTORE
TYPE: Statement
FORMAT: RESTORE
10 DATA 1,2,3,4
20 DATA 5,6,7,8
30 FOR L= 1 TO 8
40 READ A: PRINT A
50 NEXT
60 RESTORE
70 FOR L= 1 TO 8
80 READ A: PRINT A
90 NEXT
RETURN
TYPE: Statement
FORMAT: RETURN
RIGHT$
Action: The RIGHT$ function returns a sub-string taken from the right-
most end of the <string> argument. The length of the sub-string is
defined by the <numeric> argument which can be any integer in the range
of 0 to 255. If the value of the numeric expression is zero, then a null
string ("") is returned. If the value you give in the <numeric> argument
is greater than the length of the <string> then the entire string is
returned.
10 MSG$="COMMODORE COMPUTERS"
20 PRINT RIGHT$(MSG$,9)
RUN
COMPUTERS
BASIC LANGUAGE VOCABULARY 79
~
RND
RUN
TYPE: Command
FORMAT: RUN [<line-number>]
Action: The system command RUN is used to start the program currently
in memory. The RUN command causes an implied CLR operation to be
performed before starting the program. You can avoid the CLeaRing
operation by using CONT or GOTO to restart a program instead of RUN. If
a <line-number> is specified, your program will start on that line.
Otherwise, the RUN command starts at first line of the program. The RUN
command can also be used within a program. If the <line-number> you
specify doesn't exist, the BASIC error message UNDEF'D STATEMENT occurs.
A RUNning program stops and BASIC returns to direct mode when an END or
STOP statement is reached, when the last line of the program is finished,
or when a BASIC error occurs during execution.
SAVE
TYPE: Command
FORMAT: SAVE ["<file-name>"][,<device-number>][,<address>]
Action: The SAVE command is used to store the program that is cur-
rently in memory onto a tape or diskette file. The program being SAVED
is only affected by the command while the SAVE is happening. The program
remains in the current computer memory even after the SAVE operation is
completed until you put something else there by using another command.
The file type will be "prg" (program). If the <device-number> is left
out, then the C64 will automatically assume that you want the program
saved on cassette, device number 1. If the <device-number> is an <8>,
then the program is written onto disk. The SAVE statement can be used
be used in your programs and execution will continue with the next
statement after the SAVE is completed.
Programs on tape are automatically stored twice, so that your Com-
modore 64 can check for errors when LOADing the program back in. When
saving programs to tape, the <file-name> and secondary <address> are
optional. But following a SAVE with a program name in quotes ("") or
by a string variable (---$) helps your Commodore 64 find each program
more easily. If the file-name is left out it can NOT be LOADed by name
later on.
A secondary address of I will tell the KERNAL to LOAD the tape at a
later time, with the program currently in memory instead of the normal
2048 location. A secondary address of 2 will cause an end-of-tape marker
to follow the program. A secondary address of 3 combines both functions.
When saving programs onto a disk, the <file-name> must be present.
SGN
Action: SGN gives you an integer value depending upon the sign of the
<numeric> argument. If the argument is positive the result is 1, if zero
the result is also 0, if negative the result is -1.
SIN
Action: SIN gives you the sine of the <numeric> argument, in radians.
The value of COS(X) is equal to SIN(x+3.14159265/2).
235 AA=SIN(1.5):PRINT AA
.997494987
SPC
Action: SQR gives you the value of the SQuare Root of the <numeric>
argument. The value of the argument must not be negative, or the BASIC
error message ?ILLEGAL QUANTITY will happen.
10 3.16227766
15 3.87298335
20 4.47213595
25 5
READY
STATUS
variable-name into which the KERNAL puts the STATUS of I/O operations.
A table of STATUS code values for tape, printer, disk and RS-232 file
operations is shown below:
+---------+------------+---------------+------------+-------------------+
| ST Bit | ST Numeric | Cassette | Serial | Tape Verify |
| Position| Value | Read | Bus R/W | + Load |
+---------+------------+---------------+------------+-------------------+
| 0 | 1 | | time out | |
| | | | write | |
+---------+------------+---------------+------------+-------------------+
| 1 | 2 | | time out | |
| | | | read | |
+---------+------------+---------------+------------+-------------------+
| 2 | 4 | short block | | short block |
+---------+------------+---------------+------------+-------------------+
| 3 | 8 | long block | | long block |
+---------+------------+---------------+------------+-------------------+
| 4 | 16 | unrecoverable | | any mismatch |
| | | read error | | |
+---------+------------+---------------+------------+-------------------+
| 5 | 32 | checksum | | checksum |
| | | error | | error |
+---------+------------+---------------+------------+-------------------+
| 6 | 64 | end of file | EOI | |
+---------+------------+---------------+------------+-------------------+
| 7 | -128 | end of tape | device not | end of tape |
| | | | present | |
+---------+------------+---------------+------------+-------------------+
STEP
TYPE: Statement
FORMAT: [STEP <expression>]
STOP
TYPE: Statement
FORMAT: STOP
10 INPUT#1,AA,BB,CC
20 IF AA=BB AND BB=CC THEN STOP
30 STOP
(If the variable AA is -1 and BB is equal to CC then:)
BREAK IN LINE 20
BREAK IN LINE 30 (For any other data values)
STR$
Action: STR$ gives you the STRing representation of the numeric value
of the argument. When the STR$ value is converted to each variable
represented in the <numeric> argument, any number shown is followed by
a space and, if it's positive, it is also preceded by a space.
15000 15000
SYS
TYPE: Statement
FORMAT: SYS <memory-location>
Action: This is the most common way to mix a BASIC program with a
machine language program. The machine language program begins at the
location given in the SYS statement. The system command SYS is used in
either direct or program mode to transfer control of the microprocessor
to an existing machine language program in memory. The memory-location
given is by numeric expression and can be anywhere in memory, RAM or ROM.
When you're using the SYS statement you must end that section of
machine language code with an RTS (ReTurn from Subroutine) instruction
so that when the machine language program is finished, the BASIC
execution will resume with the statement following the SYS command.
TAB
Action: The TAB function moves the cursor to a relative SPC move
position on the screen given by the <numeric> argument, starting with
the left-most position of the current line. The value of the argument can
range from 0 to 255. The TAB function should only be used with the PRINT
statement, since it has no effect if used with PRINT# to a logical
file.
NAME AMOUNT
TAN
10 XX=.785398163: YY=TAN(XX):PRINT YY
TIME
EXAMPLE of TI Function:
TIME$
Action: The TI$ timer looks and works like a real clock as long as your
system is powered-on. The hardware interval timer (or jiffy clock) is
read and used to update the value of TI$, which will give you a TIme
$tring of six characters in hours, minutes and seconds. The TI$ timer can
also be assigned an arbitrary starting point similar to the way you set
your wristwatch. The value of TI$ is not accurate after tape I/O.
000011
USR
10 B=T*SIN(Y)
20 C=USR(B/2)
30 D=USR(B/3)
VAL
VERIFY
TYPE: Command
FORMAT: VERIFY ["<file-name>"][,<device>]
WAIT
TYPE: Statement
FORMAT: WAIT <location>,<mask-1>[,<mask-2>]
WAIT 1,32,32
WAIT 53273,6,6
WAIT 36868,144,16 (144 & 16 are masks. 144=10010000 in binary
and 16=10000 in binary. The WAIT statement
will halt the program until the 128 bit is
on or until the 16 bit is off)
10 GET JUNK$: IF JUNK$ <>"" THEN 10: REM EMPTY THE KEYBOARD BUFFER
In addition to GET and INPUT, the keyboard can also be read using
PEEK to fetch from memory location 197 ($00C5) the integer value of the
key currently being pressed. If no key Is being held when the PEEK is
executed, a value of 64 is returned, The numeric keyboard values,
keyboard symbols and character equivalents (CHR$) are shown in Ap-
pendix C. The following example loops until a key is pressed then con-
verts the integer to a character value.
SCREEN EDITOR
The SCREEN EDITOR provides you with powerful and convenient facilities
for editing program text. Once a section of a program is listed to the
screen, the cursor keys and other special keys are used to move around
the screen so that you can make any appropriate changes. After making all
the changes you want to a specific line-number of text, hitting the
<RETURN> key anywhere on the line, causes the SCREEN EDITOR to read the
entire 80-character logical screen line.
The <DEL> key is the only cursor control NOT affected by quote mode.
Therefore, if an error is made while keying in quote mode, the
<CRSR LEFT> key can't be used to back up and strike over the error -
even the <INST> key produces a reverse video character. Instead, finish
entering the line, and then, after hitting the <RETURN> key, you can
edit the line normally. Another alternative, if no further cursor-
controls are needed in the string, is to press the <RUN/STOP> and
<RESTORE> keys which will cancel QUOTE MODE. The cursor control keys
that you can use in strings are shown in Table 2-2.
CRSR up
CRSR down
CRSR left
CRSR right
CLR
HOME
INST
-------------------------------------------------------------------------
When you are NOT in quote mode, holding down the <SHIFT> key and then
pressing the INSerT <INST> key shifts data to the right of the cursor to
open up space between two characters for entering data between them. The
Editor then begins operating in INSERT MODE until all of the space opened
up is filled.
The cursor controls and color controls again show as reversed char-
acters in insert mode. The only difference occurs on the DELete and
INSerT <INST/DEL> key. The <DEL> instead of operating normally as in
the quote mode, now creates the reversed <T>. The <INST> key, which
created a reverse character in quote mode, inserts spaces normally.
This means that a PRINT statement can be created, containing DELetes,
which can't be done in quote mode. The insert mode is cancelled by
pressing the <RETURN>, <SHIFT> and <RETURN>, or <RUN/STOP> and <RESTORE>
keys. Or you can cancel the insert mode by filling all the inserted
spaces. An example of using DEL characters in strings is:
10 PRINT"HELLO"<DEL><INST><INST><DEL><DEL>P"
(Keystroke sequence shown above, appearance when listed below)
10 PRINT"HELP"
When the example is RUN, the word displayed will be HELP, because the
letters LO are deleted before the P is printed. The DELete character in
strings will work with LIST as well as PRINT. You can use this to "hide"
part or all of a line of text using this technique. However, trying to
edit a line with these characters will be difficult if not impossible.
There are some other characters that can be printed for special func-
tions, although they are not easily available from the keyboard. In order
to get these into quotes, you must leave empty spaces for them in the
line, press <RETURN>, and go back to edit the line. Now you hold down
the <CTRL> (ConTRoL) key and type <RVS ON> (ReVerSe-ON) to start typing
reversed characters. Type the keys as shown below:
Holding down the <SHIFT> key and hitting <RETURN> causes a carriage-
return and line-feed on the screen but does not end the string. This
works with LIST as well as PRINT, so editing will be almost impossible if
this character is used. When output is switched to the printer via the
CMD statement, the reverse "N" character shifts the printer into its
upper-lower case character set and the <SHIFT> "N" shifts the printer
into the upper-case/graphics character set.
Reverse video characters can be included in strings by holding down
the ConTRoL <CTRL> key and pressing ReVerSe <RVS>, causing a reversed R
to appear inside the quotes. This will make all characters print in
reverse video (like a negative of a photograph). To end the reverse
printing, press <CTRL> and <RVS OFF> (ReVerSe OFF) by holding down the
<CTRL> key and typing the <RVS OFF> key, which prints a reverse R.
Numeric data can be printed in reverse video by first printing a
CHR$(18). Printing a CHR$(146) or a carriage-return will cancel reverse
video output.
BASIC LANGUAGE VOCABULARY 97
~~
CHAPTER 3
PROGRAMMING
GRAPHICS
ON THE
COMMODORE 64
o Graphics Overview
o Graphics Locations
o Standard Character Mode
o Programmable Characters
o Multi-Color Mode Graphics
o Extended Background Color Mode
o Bit Mapped Graphics
o Multi-Color Bit Map Mode
o Smooth Scrolling
o Sprites
o Other Graphics Features
o Programming Sprites -
Another Look
99
~
GRAPHICS OVERVIEW
All of the graphics abilities of the Commodore 64 come from the 6567
Video Interface Chip (also known as the VIC-II chip). This chip gives a
variety of graphics modes, including a 40 column by 25 line text display,
a 320 by 200 dot high resolution display, and SPRITES, small movable
objects which make writing games simple. And if this weren't enough,
many of the graphics modes can be mixed on the same screen. It is
possible, for example, to define the top half of the screen to be in
high resolution mode, while the bottom half is in text mode. And SPRITES
will combine with anything! More on sprites later. First the other
graphics modes.
The VIC-II chip has the following graphics display modes:
C) SPRITES
1) Standard Sprites
2) Multi-Color Sprites
GRAPHICS LOCATIONS
The VIC-II chip can access ("see") 16K of memory at a time. Since there
is 64K of memory in the Commodore 64, you want to be able to have the
VIC-II chip see all of it. There is a way. There are 4 possible BANKS
(or sections) of 16K of memory. All that is needed is some means of
controlling which 16K bank the VIC-II chip looks at. In that way, the
chip can "see" the entire 64K of memory. The BANK SELECT bits that allow
you access to all the different sections of memory are located in the
6526 COMPLEX INTERFACE ADAPTER CHIP #2 (CIA #2). The POKE and PEEK BASIC
statements (or their machine language versions) are used to select a
bank, by controlling bits 0 and 1 of PORT A of CIA#2 (location 56576 (or
$DD00 HEX)). These 2 bits must be set to outputs by setting bits 0 and 1
of location 56578 ($DD02,HEX) to change banks. The following example
shows this:
+-------+------+-------+----------+-------------------------------------+
| VALUE | BITS | BANK | STARTING | VIC-II CHIP RANGE |
| OF A | | | LOCATION | |
+-------+------+-------+----------+-------------------------------------+
| 0 | 00 | 3 | 49152 | ($C000-$FFFF)* |
| 1 | 01 | 2 | 32768 | ($8000-$BFFF) |
| 2 | 10 | 1 | 16384 | ($4000-$7FFF)* |
| 3 | 11 | 0 | 0 | ($0000-$3FFF) (DEFAULT VALUE) |
+-------+------+-------+----------+-------------------------------------+
This 16K bank concept is part of everything that the VIC-II chip does.
You should always be aware of which bank the VIC-II chip is pointing at,
since this will affect where character data patterns come from, where the
screen is, where sprites come from, etc. When you turn on the power of
your Commodore 64, bits 0 and 1 of location 56576 are automatically set
to BANK 0 ($0000-$3FFF) for all display information.
+-----------------------------------------------------------------------+
| *NOTE: The Commodore 64 character set is not available to the VIC-II |
| chip in BANKS 1 and 3. (See character memory section.) |
+-----------------------------------------------------------------------+
SCREEN MEMORY
POKE53272,(PEEK(53272)AND15)OR A
COLOR MEMORY
Color memory can NOT move. It is always located at locations 55296
($D800) through 56295 ($DBE7). Screen memory (the 1000 locations starting
at 1024) and color memory are used differently in the different graphics
modes. A picture created in one mode will often look completely different
when displayed in another graphics mode.
CHARACTER MEMORY
you want to be displayed from the CHARACTER GENERATOR ROM. In this chip
are stored the patterns which make up the various letters, numbers,
punctuation symbols, and the other things that you see on the keyboard.
One of the features of the Commodore 64 is the ability to use patterns
located in RAM memory. These RAM patterns are created by you, and that
means that you can have an almost infinite set of symbols for games,
business applications, etc.
A normal character set contains 256 characters in which each character
is defined by 8 bytes of data. Since each character takes up 8 bytes this
means that a full character set is 256*8=2K bytes of memory. Since the
VIC-II chip looks at 16K of memory at a time, there are 8 possible
locations for a complete character set. Naturally, you are free to use
less than a full character set. However, it must still start at one of
the 8 possible starting locations.
The location of character memory is controlled by 3 bits of the VIC-II
control register located at 53272 ($D018 in HEX notation). Bits 3,2, and
1 control where the characters' set is located in 2K blocks. Bit 0 is ig-
nored. Remember that this is the same register that determines where
screen memory is located so avoid disturbing the screen memory bits. To
change the location of character memory, the following BASIC statement
can be used:
POKE 53272,(PEEK(53272)AND240)OR A
The ROM IMAGE in the above table refers to the character generator ROM.
It appears in place of RAM at the above locations in bank 0. it also
appears in the corresponding RAM at locations 36864-40959 ($9000-$9FFF)
in bank 2. Since the VIC-II chip can only access 16K of memory at a time,
the ROM character patterns appear in the 16K block of memory the VIC-II
chip looks at. Therefore, the system was designed to make the VIC-II chip
think that the ROM characters are at 4096-8191 ($1000-$1FFF) when your
data is in bank 0, and 36864-40959 ($9000-$9FFF) when your data is in
bank 2, even though the character ROM is actually at location 53248-57343
($D000-$DFFF). This imaging only applies to character data as seen by the
VIC-II chip. It can be used for programs, other data, etc., just like any
other RAM memory.
+-----------------------------------------------------------------------+
| NOTE: If these ROM images got in the way of your own graphics, then |
| set the BANK SELECT BITS to one of the BANKS without the images |
| (BANKS 1 or 3). The ROM patterns won't be there. |
+-----------------------------------------------------------------------+
The location and contents of the character set in ROM are as follows:
+-----+-------------------+-----------+---------------------------------+
| | ADDRESS | VIC-II | |
|BLOCK+-------+-----------+ IMAGE | CONTENTS |
| |DECIMAL| HEX | | |
+-----+-------+-----------+-----------+---------------------------------+
| 0 | 53248 | D000-D1FF | 1000-11FF | Upper case characters |
| | 53760 | D200-D3FF | 1200-13FF | Graphics characters |
| | 54272 | D400-D5FF | 1400-15FF | Reversed upper case characters |
| | 54784 | D600-D7FF | 1600-17FF | Reversed graphics characters |
| | | | | |
| 1 | 55296 | D800-D9FF | 1800-19FF | Lower case characters |
| | 55808 | DA00-DBFF | 1A00-1BFF | Upper case & graphics characters|
| | 56320 | DC00-DDFF | 1C00-1DFF | Reversed lower case characters |
| | 56832 | DE00-DFFF | 1E00-1FFF | Reversed upper case & |
| | | | | graphics characters |
+-----+-------+-----------+-----------+---------------------------------+
character data the ROM is switched in. It becomes an image in the 16K
bank of memory that the VIC-II chip is looking at. Otherwise, the area is
occupied by the I/O control registers, and the character ROM is only
available to the VIC-II chip.
However, you may need to get to the character ROM if you are going to
use programmable characters and want to copy some of the character ROM
for some of your character definitions. In this case you must switch out
the I/O register, switch in the character ROM, and do your copying. When
you're finished, you must switch the 1/0 registers back in again. During
the copying process (when I/O is switched out) no interrupts can be
allowed to take place. This is because the I/O registers are needed to
service the interrupts. If you forget and perform an interrupt, really
strange things happen. The keyboard should not be read during the copying
process. To turn off the keyboard and other normal interrupts that occur
with your Commodore 64, the following POKE should be used:
After you are finished getting characters from the character ROM, and
are ready to continue with your program, you must turn the keyboard scan
back on by the following POKE:
The following POKE will switch out 1/0 and switch the CHARACTER ROM in:
POKE 1,PEEK(1)AND251
POKE 1,PEEK(1)OR 4
CHARACTER DEFINITIONS
53256 ($D008) to 53263 ($D00F), contain the information for forming the
letter A.
** 00011000 24
**** 00111100 60
** ** 01100110 102
****** 01111110 126
** ** 01100110 102
** ** 01100110 102
** ** 01100110 102
00000000 0
PROGRAMMABLE CHARACTERS
Since the characters are stored in ROM, it would seem that there is no
way to change them for customizing characters. However, the memory
location that tells the VIC-II chip where to find the characters is a
programmable register which can be changed to point to many sections of
memory. By changing the character memory pointer to point to RAM, the
character set may be programmed for any need.
If you want your character set to be located in RAM, there are a few
VERY IMPORTANT things to take into account when you decide to actually
program your own character sets. In addition, there are two other
important points you must know to create your own special characters:
2) Your character set takes memory space away from your BASIC program.
Of course, with 38K available for a BASIC program, most applications
won't have problems.
+-----------------------------------------------------------------------+
| WARNING: You must be careful to protect the character set from being |
| overwritten by your BASIC program, which also uses the RAM. |
+-----------------------------------------------------------------------+
There are two locations in the Commodore 64 to start your character set
that should NOT be used with BASIC: location 0 and location 2048. The
first should not be used because the system stores important data on
page 0. The second can't be used because that is where your BASIC program
starts! However, there are 6 other starting positions for your custom
character set.
The best place to put your character set for use with BASIC while
experimenting is beginning at 12288 ($3000 in HEX). This is done by
POKEing the low 4 bits of location 53272 with 12. Try the POKE now, like
this:
POKE 53272,(PEEK(53272)AND240)+12
PRINT FRE(0)-(SGN(FRE(0))<0)*65535
The number displayed is the amount of memory space left unused. Now
type the following:
POKE 52148:POKE56,48:CLR
Now type:
PRINT FRE(0)-(SGN(FRE(0))<0)*65535
See the change? BASIC now thinks it has less memory to work with. The
memory you just claimed from BASIC is where you are going to put your
character set, safe from actions of BASIC.
The next step is to put your characters into RAM. When you begin, there
is random data beginning at 12288 ($3000 HEX). You must put character
patterns in RAM (in the same style as the ones in ROM) for the VIC-II
chip to use.
The following program moves 64 characters from ROM to your character
set RAM:
+-----------------------------------------------------------------------+
| TIP: Reversed characters are just characters with their bit patterns |
| in character memory reversed. |
+-----------------------------------------------------------------------+
Now move the cursor up to the program again and hit <RETURN> again to
re-reverse the character (bring it back to normal). By looking at the
table of screen display codes, you can figure out where in RAM each
character is. Just remember that each character takes eight memory
locations to store. Here's a few examples just to get you started:
+-----------+--------------+--------------------------------------------+
| CHARACTER | DISPLAY CODE | CURRENT STARTING LOCATION IN RAM |
+-----------+--------------+--------------------------------------------+
| @ | 0 | 1228 |
| A | 1 | 12296 |
| ! | 33 | 12552 |
| > | 62 | 12784 |
+-----------+--------------+--------------------------------------------+
Remember that we only took the first 64 characters. Something else will
have to be done if you want one of the other characters.
What if you wanted character number 154, a reversed Z? Well, you could
make it yourself, by reversing a Z, or you could copy the set of reversed
characters from the ROM, or just take the one character you want from ROM
and replace one of the characters you have in RAM that you don't need.
Suppose you decide that you won't need the > sign. Let's replace the
> sign with the reversed Z. Type this:
Now type RUN. The program will replace the letter T with a smile face
character. Type a few T's to see the face. Each of the numbers in the
DATA statement in line 20 is a row in the smile face character. The
matrix for the face looks like this:
+--------+
ROW 0 | **** | 00111100 60
1 | * * | 01000010 66
2 |* * * *| 10100101 165
3 |* *| 10000001 129
4 |* * * *| 10100101 165
5 |* ** *| 10011001 153
6 | * * | 01000010 66
ROW 7 | **** | 00111100 60
+--------+
7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+
0 | | | | | | | | |
+-+-+-+-+-+-+-+-+
1 | | | | | | | | |
+-+-+-+-+-+-+-+-+
2 | | | | | | | | |
+-+-+-+-+-+-+-+-+
3 | | | | | | | | |
+-+-+-+-+-+-+-+-+
4 | | | | | | | | |
+-+-+-+-+-+-+-+-+
5 | | | | | | | | |
+-+-+-+-+-+-+-+-+
6 | | | | | | | | |
+-+-+-+-+-+-+-+-+
7 | | | | | | | | |
+-+-+-+-+-+-+-+-+
The Programmable Character Worksheet (Figure 3-1) will help you design
your own characters. There is an 8 by 8 matrix on the sheet, with row
numbers, and numbers at the top of each column. (if you view each row as
a binary word, the numbers are the value of that bit position. Each is a
power of 2. The leftmost bit is equal to 128 or 2 to the 7th power, the
next is equal to 64 or 2 to the 6th, and so on, until you reach the
rightmost bit (bit 0) which is equal to 1 or 2 to the 0 power.)
Place an X on the matrix at every location where you want a dot to be
in your character. When your character is ready you can create the DATA
statement for your character.
Begin with the first row. Wherever you placed an X, take the number at
the top of the column (the power-of-2 number, as explained above) and
write it down. When you have the numbers for every column of the first
row, add them together. \Mite this number down, next to the row. This is
the number that you will put into the DATA statement to draw this row.
Do the same thing with all of the other rows (1-7). When you are
finished you should have 8 numbers between 0 and 255. If any of your
numbers are not within range, recheck your addition. The numbers must be
in this range to be correct! If you have less than 8 numbers, you missed
a row. It's OK if some are 0. The 0 rows are just as important as the
other numbers.
Replace the numbers in the DATA statement in line 20 with the numbers
you just calculated, and RUN the program. Then type a T. Every time you
type it, you'll see your own character!
If you don't like the way the character turned out, just change the
numbers in the DATA statement and re-RUN the program until you are happy
with your character.
That's all there is to it!
+-----------------------------------------------------------------------+
| HINT: For best results, always make any vertical lines in your |
| characters at least 2 dots (bits) wide. This helps prevent CHROMA |
| noise (color distortion) on your characters when they are displayed |
| on a TV screen. |
+-----------------------------------------------------------------------+
POKE 53270,PEEK(53270)OR 16
Multi-color mode is set on or off for each space on the screen, so that
multi-color graphics can be mixed with high-resolution (hi-res) graphics.
This is controlled by bit 3 in color memory. Color memory begins at
location 55296 ($D800 in HEX). If the number in color memory is less than
8 (0-7) the corresponding space on the video screen will be standard
hi-res, in the color (0-7) you've chosen. If the number located in color
memory is greater or equal to 8 (from 8 to 15), then that space will be
displayed in multi-color mode.
** 00011000
**** 00111100
** ** 01100110
****** 01111110
** ** 01100110
** ** 01100110
** ** 01100110
00000000
AABB 00011000
CCCC 00111100
AABBAABB 01100110
AACCCCBB 01111110
AABBAABB 01100110
AABBAABB 01100110
AABBAABB 01100110
00000000
In the image area above, the spaces marked AA are drawn in the
background #1 color, the spaces marked BB use the background #2 color,
and the spaces marked CC use the character color. The bit pairs determine
this, according to the following chart:
+----------+--------------------------------------+---------------------+
| BIT PAIR | COLOR REGISTER | LOCATION |
+----------+--------------------------------------+---------------------+
| 00 | Background #0 color (screen color) | 53281 ($D021) |
| 01 | Background #l color | 53282 ($D022) |
| 10 | Background #2 color | 53283 ($D023) |
| 11 | Color specified by the | color RAM |
| | lower 3 bits in color memory | |
+----------+--------------------------------------+---------------------+
Type NEW and then type this demonstration program:
The screen color is white, the character color is black, one color
register is cyan (greenish blue), the other is orange. You're not really
putting color codes in the space for character color, you're actually
using references to the registers associated with those colors. This
conserves memory, since 2 bits can be used to pick 16 colors (background)
or 8 colors (character). This also makes some neat tricks possible.
Simply changing one of the indirect registers will change every dot drawn
in that color. Therefore everything drawn in the screen and background
The word READY and anything else you type will be displayed in multi-
color mode. Another color control can set you back to regular text.
Extended background color mode gives you control over the background
color of each individual character, as well as over the foreground color.
For example, in this mode you could display a blue character with a
yellow background on a white screen.
There are 4 registers available for extended background color mode.
Each of the registers can be set to any of the 16 colors.
Color memory is used to hold the foreground color in extended back-
ground mode. It is used the same as in standard character mode.
Extended character mode places a limit on the number of different
characters you can display, however. When extended color mode is on, only
the first 64 characters in the character ROM (or the first 64 characters
in your programmable character set) can be used. This is because two of
the bits of the character code are used to select the background color.
It might work something like this:
The character code (the number you would POKE to the screen) of the
letter "A" is a 1. When extended color mode is on, if you POKED a 1 to
the screen, an "A" would appear. If you POKED a 65 to the screen
normally, you would expect the character with character code (CHR$) 129
to appear, which is a reversed "A." This does NOT happen in extended
color mode. Instead you get the same unreversed "A" as before, but on a
different background color. The following chart gives the codes:
+------------------------+---------------------------+
| CHARACTER CODE | BACKGROUND COLOR REGISTER |
+------------------------+---------------------------+
| RANGE BIT 7 BIT 6 | NUMBER ADDRESS |
+------------------------+---------------------------+
| 0- 63 0 0 | 0 53281 ($D021) |
| 64-127 0 1 | 1 53282 ($D022) |
| 128-191 1 0 | 2 53283 ($D023) |
| 192-255 1 1 | 3 53284 ($D024) |
+------------------------+---------------------------+
POKE 53265,PEEK(53265)OR 64
Extended color mode is turned OFF by setting bit 6 of the VIC-II regis-
ter to a 0 at location 53265 ($D011). The following statement will do
this:
8K section of memory on the TV screen. When in bit map mode, you can
directly control whether an individual dot on the screen is on or off.
There are two types of bit mapping available on the Commodore 64.
They are:
Standard bit map mode gives you a 320 horizontal dot by 200 vertical
dot resolution, with a choice of 2 colors in each 8-dot by 8-dot section.
Bit map mode is selected (turned ON) by setting bit 5 of the VIC-II
control register to a 1 at location 53265 ($D011 in HEX). The following
POKE will do this:
POKE 53265,PEEK(53265)OR 32
Bit map mode is turned OFF by setting bit 5 of the VIC-II control
register to 0 at location 53265 ($D011), like this:
Before we get into the details of the bit map mode, there is one more
issue to tackle, and that is where to locate the bit map area.
HOW IT WORKS
screen is filled with programmable characters, and you make your changes
directly into the memory that the programmable characters get their
patterns from.
Each of the locations in screen memory that were used to control what
character was displayed, are now used for color information. For example,
instead of POKEing a I in location 1024 to make an "A" appear in the top
left hand corner of the screen, location 1024 now controls the colors of
the bits in that top left space.
Colors of squares in bit map mode do not come from color memory, as
they do in the character modes. Instead, colors are taken from screen
memory. The upper 4 bits of screen memory become the color of any bit
that is set to 1 in the 8 by 8 area controlled by that screen memory
location. The lower 4 bits become the color of any bit that is set to
a 0.
Now RUN the program again. You should see the screen clearing, then the
greenish blue color, cyan, should cover the whole screen. What we want to
do now is to turn the dots on and off on the HI-RES screen.
To SET a dot (turn a dot ON) or UNSET a dot (turn a dot OFF) you must
know how to find the correct bit in the character memory that you have to
set to a 1. In other words, you have to find the character you need to
change, the row of the character, and which bit of the row that you
have to change. You need a formula to calculate this.
We will use X and Y to stand for the horizontal and vertical positions
of a dot, The dot where X=0 and Y=0 is at the upper-left of the display.
Dots to the right have higher X values, and the dots toward the bottom
have higher Y values. The best way to use bit mapping is to arrange the
bit map display something like this:
0. . . . . . . . . . . . . . . . . .X. . . . . . . . . . . . . . . . .319
. .
. .
. .
. .
Y .
. .
. .
. .
. .
199. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Each dot will have an X and a Y coordinate. With this format it is easy
to control any dot on the screen.
----- BYTE 320 BYTE 328 BYTE 336 BYTE 344....................... BYTE 632
BYTE 321 BYTE 329 . . BYTE 633
BYTE 322 BYTE 330 . . BYTE 634
BYTE 323 BYTE 331 . . BYTE 635
BYTE 324 BYTE 332 . . BYTE 636
BYTE 325 BYTE 333 . . BYTE 637
BYTE 326 BYTE 334 . . BYTE 638
----- BYTE 327 BYTE 335 . . BYTE 639
The programmable characters which make up the bit map are arranged in
25 rows of 40 columns each. While this is a good method of organization
for text, it makes bit mapping somewhat difficult. (There is a good
reason for this method. See the section on MIXED MODES.)
The following formula will make it easier to control a dot on the bit
map screen:
The start of the display memory area is known as the BASE, The row
number (from 0 to 24) of your dot is:
LINE = Y AND 7
PROGRAMMING GRAPHICS 125
~
Now we put these formulas together. The byte in which character memory
dot (X,Y) is located is calculated by:
To turn on any bit on the grid with coordinates (X,Y), use this line:
The calculation in line 60 will change the values for the sine function
from a range of +1 to -1 to a range of 10 to 170. Lines 70 to 100
calculate the character, row, byte, and bit being affected, using the
formulae as shown above. Line 125 signals the program is finished by
changing the color of the top left corner of the screen. Line 130 freezes
the program by putting it into an infinite loop. When you have finished
looking at the display, just hold down <RUN/STOP> and hit <RESTORE>.
As a further example, you can modify the sine curve program to display
a semicircle. Here are the lines to type to make the changes:
+-----------------------------------------------------------------------+
| WARNING: BASIC variables can overlay your high-resolution screen. If |
| you need more memory space you must move the bottom of BASIC above the|
| high-resolution screen area. Or, you must move your high-resolution |
| screen area. This problem will NOT occur in machine language. It ONLY |
| happens when you're writing programs in BASIC. |
+-----------------------------------------------------------------------+
Like multi-color mode characters, multi-color bit map mode allows you
to display up to four different colors in each 8 by 8 section of bit map.
And as in multi-character mode, there is a sacrifice of horizontal
resolution (from 320 dots to 160 dots).
Multi-color bit map mode uses an 8K section of memory for the bit map.
You select your colors for multi-color bit map mode from (1) the
background color register 0, (the screen background color), (2) the video
matrix (the upper 4 bits give one possible color, the lower 4 bits an-
other), and (3) color memory.
Multi-color bit mapped mode is turned ON by setting bit 5 of 53265
($D011) and bit 4 at location 53270 ($D016) to a 1. The following POKE
does this:
SMOOTH SCROLLING
The VIC-II chip supports smooth scrolling in both the horizontal and
vertical directions. Smooth scrolling is a one pixel movement of the
entire screen in one direction. It can move either UP, or down, or left,
or right. It is used to move new information smoothly onto the screen,
while smoothly removing characters from the other side.
While the VIC-II chip does much of the task for you, the actual scroll-
ing must be done by a machine language program. The VIC-II chip features
the ability to place the video screen in any of 8 horizontal positions,
and 8 vertical positions. Positioning is controlled by the VIC-II
scrolling registers. The VIC-II chip also has a 38 column mode, and a 24
row mode. the smaller screen sizes are used to give you a place for your
new data to scroll on from.
POKE 53270,PEEK(53270)OR 8
register is set to 0, the first line is covered, ready for new data. When
the Y scrolling register is set to 7 the last row is covered.
For scrolling in the X direction, the scroll register is located in
bits 2 to 0 of the VIC-II control register at location 53270 ($D016 in
HEX). As always, it is important to affect only those bits. The following
POKE does this:
SPRITES
DEFINING A SPRITE
SPRITE POINTERS
Even though each sprite takes only 63 bytes to define, one more byte
is needed as a place holder at the end of each sprite. Each sprite, then,
takes up 64 bytes. This makes it easy to calculate where in memory your
sprite definition is, since 64 bytes is an even number and in binary it's
an even power.
Each of the 8 sprites has a byte associated with it called the SPRITE
POINTER. The sprite pointers control where each sprite definition is lo-
cated in memory. These 8 bytes are always located as the lost 8 bytes
of the 1K chunk of screen memory. Normally, on the Commodore 64, this
means they begin at location 2040 ($07F8 in HEX). However, if you move
the screen, the location of your sprite pointers will also move.
Each sprite pointer can hold a number from 0 to 255. This number points
to the definition for that sprite. Since each sprite definition takes
64 bytes, that means that the pointer can "see" anywhere in the 16K
block of memory that the VIC-II chip can access (since 256*64=16K).
If sprite pointer #0, at location 2040, contains the number 14, for
example, this means that sprite 0 will be displayed using the 64 bytes
beginning at location 14*64 = 896 which is in the cassette buffer. The
following formula makes this clear:
Where BANK is the 16K segment of memory that the VIC-II chip is looking
at and is from 0 to 3.
The above formula gives the start of the 64 bytes of the sprite
definition block.
When the VIC-II chip is looking at BANK 0 or BANK 2, there is a ROM
IMAGE of the character set present in certain locations, as mentioned
before. Sprite definitions can NOT be placed there. If for some reason
you need more than 128 different sprite definitions, you should use one
of the banks without the ROM IMAGE, 1 or 3.
TURNING SPRITES ON
POKE 53269.PEEK(53269)OR 2
+-----------------------------------------------------------------------+
| NOTE: A sprite must be turned ON before it can be seen. |
+-----------------------------------------------------------------------+
POKE 53269,PEEK(53269)AND(255-2^SN)
COLORS
A sprite can be any of the 16 colors generated by the VIC-II chip. Each
of the sprites has its own sprite color register. These are the memory
locations of the color registers:
ADDRESS | DESCRIPTION
--------------------------+----------------------------------------------
53287 ($D027) | SPRITE 0 COLOR REGISTER
53288 ($D028) | SPRITE 1 COLOR REGISTER
53289 ($D029) | SPRITE 2 COLOR REGISTER
53290 ($D02A) | SPRITE 3 COLOR REGISTER
53291 ($D02B) | SPRITE 4 COLOR REGISTER
53292 ($D02C) | SPRITE 5 COLOR REGISTER
53293 ($D02D) | SPRITE 6 COLOR REGISTER
53294 ($D02E) | SPRITE 7 COLOR REGISTER
All dots in the sprite will be displayed in the color contained in the
sprite color register. The rest of the sprite will be transparent, and
will show whatever is behind the sprite.
MULTI-COLOR MODE
turn ON each of the four colors you've chosen for your sprite:
To switch a sprite into multi-color mode you must turn ON the VIC-II
control register at location 53276 ($D01C). The following POKE does this:
POKE 53276,PEEK(53276)OR(2^SN)
POKE 53276,PEEK(53276)AND(255-2^SN)
EXPANDED SPRITES
The VIC-II chip has the ability to expand a sprite in the vertical
direction, the horizontal direction, or both at once. When expanded, each
dot in the sprite is twice as wide or twice as tall. Resolution doesn't
actually increase... the sprite just gets bigger.
To expand a sprite in the horizontal direction, the corresponding bit
in the VIC-II control register at location 53277 ($D01D in HEX) must be
turned ON (set to a 1). The following POKE expands a sprite in the X
direction:
POKE 53277,PEEK(53277)OR(2^SN)
POKE 53271,PEEK(53271)OR(2^SN)
SPRITE POSITIONING
Once you've made a sprite you want to be able to move it around the
screen. To do this, your Commodore 64 uses three positioning registers:
Next comes the X register for sprite 1, the Y register for sprite 1, and
so on. After all 16 X and Y registers comes the most significant bit in
the X position (X MSB) located in its own register.
The chart below lists the locations of each sprite position register.
You use the locations at their appropriate time through POKE statements:
+-------------------+---------------------------------------------------+
| LOCATION | |
+---------+---------+ DESCRIPTION |
| DECIMAL | HEX | |
+---------+---------+---------------------------------------------------+
| 53248 | ($D000) | SPRITE 0 X POSITION REGISTER |
| 53249 | ($D001) | SPRITE 0 Y POSITION REGISTER |
| 53250 | ($D002) | SPRITE 1 X POSITION REGISTER |
| 53251 | ($D003) | SPRITE 1 Y POSITION REGISTER |
| 53252 | ($D004) | SPRITE 2 X POSITION REGISTER |
| 53253 | ($D005) | SPRITE 2 Y POSITION REGISTER |
| 53254 | ($D006) | SPRITE 3 X POSITION REGISTER |
| 53255 | ($D007) | SPRITE 3 Y POSITION REGISTER |
| 53256 | ($D008) | SPRITE 4 X POSITION REGISTER |
| 53257 | ($D009) | SPRITE 4 Y POSITION REGISTER |
| 53258 | ($D00A) | SPRITE 5 X POSITION REGISTER |
| 53259 | ($D00B) | SPRITE 5 Y POSITION REGISTER |
| 53260 | ($D00C) | SPRITE 6 X POSITION REGISTER |
| 53261 | ($D00D) | SPRITE 6 Y POSITION REGISTER |
| 53262 | ($D00E) | SPRITE 7 X POSITION REGISTER |
| 53263 | ($D00F) | SPRITE 7 Y POSITION REGISTER |
| 53264 | ($D010) | SPRITE X MSB REGISTER |
+---------+---------+---------------------------------------------------+
The position of a sprite is calculated from the TOP LEFT corner of the
24 dot by 21 dot area that your sprite can be designed in. It does NOT
matter how many or how few dots you use to make up a sprite. Even if only
one dot is used as a sprite, and you happen to want it in the middle of
the screen, you must still calculate the exact positioning by starting at
the top left corner location.
VERTICAL POSITIONING
There are 200 different dot positions that can be individually pro-
grammed onto your TV screen in the Y direction. The sprite Y position
registers can handle numbers up to 255. This means that you have more
than enough register locations to handle moving a sprite up and down. You
also want to be able to smoothly move a sprite on and off the screen.
More than 200 values are needed for this.
The first on-screen value from the top of the screen, and in the Y
direction for an unexpanded sprite is 30. For a sprite expanded in the Y
direction it would be 9. (Since each dot is twice as tall, this makes a
certain amount of sense, as the initial position is STILL calculated from
the top left corner of the sprite.)
The first Y value in which a sprite (expanded or not) is fully on the
screen (all 21 possible lines displayed) is 50.
The last Y value in which an unexpanded sprite is fully on the screen
is 229. The last Y value in which an expanded sprite is fully on the
screen is 208.
The first Y value in which a sprite is fully off the screen is 250.
EXAMPLE:
HORIZONTAL POSITIONING
EXAMPLE:
When moving expanded sprites onto the left side of the screen in the
X direction, you have to start the sprite OFF SCREEN on the RIGHT SIDE.
This is because an expanded sprite is larger than the amount of space
available on the left side of the screen.
EXAMPLE:
Sprites have the ability to cross each other's paths, as well as cross
in front of, or behind other objects on the screen. This can give you a
truly three dimensional effect for games.
Sprite to sprite priority is fixed. That means that sprite 0 has the
highest priority, sprite 1 has the next priority, and so on, until we get
to sprite 7, which has the lowest priority. In other words, if sprite 1
and sprite 6 are positioned so that they cross each other, sprite 1 will
be in front of sprite 6.
So when you're planning which sprites will appear to be in the fore-
ground of the picture, they must be assigned lower sprite numbers than
those sprites you want to put towards the back of the scene. Those
sprites will be given higher sprite numbers,
+-----------------------------------------------------------------------+
| NOTE: A "window" effect is possible. If a sprite with higher priority |
| has "holes" in it (areas where the dots are not set to 1 and thus |
| turned ON), the sprite with the lower priority will show through. This|
| also happens with sprite and background data. |
+-----------------------------------------------------------------------+
COLLISION DETECTS
One of the more interesting aspects of the VIC-II chip is its collision
detection abilities. Collisions can be detected between sprites, or be-
tween sprites and background data. A collision occurs when a non-zero
part of a sprite overlaps a non-zero portion of another sprite or char-
acters on the screen.
+-----------------------------------------------------------------------+
| NOTE: Collisions can take place even when the sprites are off screen. |
+-----------------------------------------------------------------------+
+-----------------------------------------------------------------------+
| NOTE: MULTI-COLOR data 01 is considered transparent for collisions, |
| even though it shows up on the screen. When setting up a background |
| screen, it is a good idea to make everything that should not cause a |
| collision 01 in multi-color mode. |
+-----------------------------------------------------------------------+
SCREEN BLANKING
Bit 4 of the VIC-II control register controls the screen blanking func-
tion. It is found in the control register at location 53265 ($D011). When
it is turned ON (in other words, set to a 1) the screen is normal. When
bit 4 is set to 0 (turned OFF), the entire screen changes to border
color.
The following POKE blanks the screen. No data is lost, it just isn't
displayed.
POKE 53265,PEEK(53265)OR 16
+-----------------------------------------------------------------------+
| NOTE: Turning off the screen will speed up the processor slightly. |
| This means that program RUNning is also sped up. |
+-----------------------------------------------------------------------+
RASTER REGISTER
+-----------------------------------------------------------------------+
| NOTE: If the proper interrupt bit is enabled (turned on), an interrupt|
| (IRQ) will occur. |
+-----------------------------------------------------------------------+
The interrupt status register shows the current status of any interrupt
source. The current status of bit 2 of the interrupt register will be a 1
when two sprites hit each other. The same is true, in a corresponding 1
to 1 relationship, for bits 0-3 listed in the chart below. Bit 7 is also
set with a 1, whenever an interrupt occurs.
The interrupt status register is located at 53273 ($D019) and is as
follows:
Color TV sets are limited in their ability to place certain colors next
to each other on the same line. Certain combinations of screen and char-
acter colors produce blurred images. This chart shows which color com-
binations to avoid, and which work especially well together.
CHARACTER COLOR
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
0| x| o| x| o| o| /| x| o| o| x| o| o| o| o| o| o|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1| o| x| o| x| o| o| o| x| /| o| /| o| o| x| o| o|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
2| x| o| x| x| /| x| x| o| o| x| o| x| x| x| x| /|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
3| o| x| x| x| x| /| o| x| x| x| x| /| x| x| /| x|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
4| o| /| x| x| x| x| x| x| x| x| x| x| x| x| x| /|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
5| o| /| x| /| x| x| x| x| x| x| x| /| x| o| x| /|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
SCREEN 6| /| o| x| o| x| x| x| x| x| x| x| x| x| /| o| o|
COLOR +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
7| o| x| o| x| x| x| /| x| /| o| /| o| o| x| x| x|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
8| /| o| o| x| x| x| x| o| x| o| x| x| x| x| x| /|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9| x| o| x| x| x| x| x| o| o| x| o| x| x| x| x| o|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10| /| /| o| x| x| x| x| /| x| o| x| x| x| x| x| /| o = EXCELLENT
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11| o| o| x| /| x| x| x| o| x| x| x| x| o| o| /| o| / = FAIR
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
12| o| o| /| x| x| x| /| x| x| /| x| o| x| x| x| o| x = POOR
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
13| o| x| x| x| x| o| /| x| x| x| x| o| x| x| x| x|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
14| o| o| x| o| x| x| o| x| x| x| x| /| x| x| x| /|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
15| o| o| o| x| /| /| o| x| x| /| /| o| o| x| /| x|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
This program includes the key "ingredients" you need to create any
sprite. The POKE numbers come from the SPRITEMAKING CHART on Page 176.
This program defines the first sprite... sprite 0... as a solid white
square on the screen. Here's a line-by-line explanation of the program:
LINE 20 sets the "sprite pointer" to where the Commodore 64 will read
its sprite data from. Sprite 0 is set at 2040, sprite 1 at 2041, sprite
2 at 2042, and so on up to sprite 7 at 2047. You can set all 8 sprite
pointers to 13 by using this line in place of line 20:
LINE 30 puts the first sprite (sprite 0) into 63 bytes of the Commodore
64's RAM memory starting at location 832 (each sprite requires 63 bytes
LINE 40 sets the variable "V" equal to 53248, the starting address of
the VIDEO CHIP. This entry lets us use the form (V+number) for sprite
settings. 're using the form (V+number) when POKEing sprite settings
because this format conserves memory and lets us work with smaller
numbers. For example, in line 50 we typed POKE V+21. This is the same as
typing POKE 53248+21 or POKE 53269... but V+21 requires less space than
53269, and is easier to remember.
POKE V+39,8
The sprite on the screen is now ORANGE. Try POKEing some other numbers
from 0 to 15 to see the other sprite colors. Because you did this in
DIRECT mode, if you RUN your program the sprite will return to its origi-
nal color (white).
LINE 70, determines the HORIZONTAL or "X" POSITION of the sprite on the
screen. This number represents the location of the UPPER LEFT CORNER of
the sprite. The farthest left horizontal (X) position which you can see
on your television screen is position number 24, although you can move
the sprite OFF THE SCREEN to position number 0.
This places the sprite at the upper left corner of the screen. To move
the sprite to the lower left corner, type this:
Each number from 832 to 895 in our sprite 0 address represents one
block of 8 pixels, with three 8-pixel blocks in each horizontal row of
the sprite. The loop in line 80 tells the computer to POKE 832,255 which
makes the first 8 pixels solid . . . then POKE 833,255 to make the second
8 pixels solid, and so on to location 894 which is the last group of 8
pixels in the bottom right corner of the sprite. To better see how this
works, try typing the following in DIRECT r-node, and notice that the
second group of 8 pixels is erased:
POKE 833,0 (to put it back type POKE 833,255 or RUN your program)
The following line, which you can add to your program. erases the
blocks in the MIDDLE of the sprite you created:
Remember, the pixels that make up the sprite are grouped in blocks of
eight. This line erases the 5th group of eight pixels (block 836) and
every third block up to block 890. Try POKEing any of the other numbers
from 832 to 894 with either a 255 to make them solid or 0 to make them
blank.
+-----------------------------------------------------------------------+
| CRUNCHING YOUR SPRITE PROGRAMS |
| |
| Here's a helpful "crunching" tip: The program described above is |
| already short, but it can be made even shorter by "crunching" it |
| smaller. In our example we list the key sprite settings on separate |
| program lines so you can see what's happening in the program. In |
| actual practice, a good programmer would probably write this program |
| as a TWO LINE PROGRAM... by "crunching" it as follows: |
| |
| 10 PRINTCHR$(147):V=53248:POKEV+21,1:POKE2040.13:POKEV+39,1 |
| 20 FORS=832TO894:POKES,255:NEXT:POKEV,24:POKEV+1,100 |
| |
| For more tips on how to crunch your programs so they fit in less |
| memory and run more efficiently, see the "crunching guide" on Page 24.|
+-----------------------------------------------------------------------+
TV SCREEN
+---------------------------------------------------+
| ^ |
| | |
|<-------+---- X POSITION = HORIZONTAL ------------>|
| | |
| | |
| | |
| | |
| | |
| | +-+ |
| | | | |
| | +-+ |
| | / |
| | / |
| | / |
| | / |
+-------------------------------/-------------------+
/
A sprite located here must have both its X-position (horizontal) and
Y-position (vertical) set so it can be displayed on the screen.
Figure 3-4. The display screen is divided into a grid of X and Y coor-
dinates.
+------+-------+-------+-------+-------+-------+-------+-------+--------+
| |SPRT 0 |SPRT 1 |SPRT 2 |SPRT 3 |SPRT 4 |SPRT 5 |SPRT 6 |SPRT 7 |
+------+-------+-------+-------+-------+-------+-------+-------+--------+
|SET X |V,X |V+2,X |V+4,X |V+6,X |V+8,X |V+10,X |V+12,X |V+14,X |
|SET Y |V+1,Y |V+3,Y |V+5,Y |V+7,Y |V+9,Y |V+11,Y |V+13,Y |V+15,Y |
|RIGHTX|V+16,1 |V+16,2 |V+16,4 |V+16,8 |V+16,16|V+16,32|V+16,64|V+16,128|
+------+-------+-------+-------+-------+-------+-------+-------+--------+
X VALUES BEYOND THE 255TH POSITION: To get beyond the 255th position
across the screen, you need to make a SECOND POKE using the numbers in
the "RIGHT X" row of the chart (Figure 3-5). Normally, the horizontal (X)
numbering would continue past the 255th position to 256, 257, etc., but
because registers only contain 8 bits we must use a "second register" to
access the RIGHT SIDE of the screen and start our X numbering over again
at 0. So to get beyond X position 255, you must POKE V+16 and a number
(depending on the sprite). This gives you 65 additional X positions
(renumbered from 0 to 65) in the viewing area on the RIGHT side of the
viewing screen. (You can actually POKE the right side X value as high as
255, which takes you off the right edge of the viewing screen.)
Let's see how this X-Y positioning works, using sprite 1. Type this
program:
start tok64 page159.prg
10 print"{clear}":v=53248:pokev+21,2:poke2041,13
20 fors=832to895:pokes,255:next:pokev+40,7
30 pokev+2,24
40 pokev+3,50
stop tok64
This simple program establishes sprite 1 as a solid box and positions it
at the upper left corner of the screen. Now change line 40 to read:
40 POKE V+3,229
This moves the sprite to the bottom left corner of the screen. Now let's
test the RIGHT X LIMIT of the sprite. Change line 30 as shown:
30 POKE V+2,255
This moves the sprite to the RIGHT but reaches the RIGHT X LIMIT, which
is 255. At this point, the "most significant bit" in register 16 must be
SET. In other words, you must type POKE V+ 16 and the number shown in the
"RIGHT X" column in the X-Y POKE CHART above to RESTART the X position
counter at the 256th pixel/position on the screen. Change line 30 as
follows:
POKE V+16,2 sets the most significant bit of the X position for sprite 1
and restarts it at the 256th pixel/position on the screen. POKE V+2,0
displays the sprite at the NEW POSITION ZERO, which is now reset to the
256th pixel.
To get back to the left side of the screen, you must reset the most
significant bit of the X position counter to 0 by typing (for sprite 1):
TO SUMMARIZE how the X positioning works... POKE the X POSITION for any
sprite with a number from 0 to 255. To access a position beyond the 255th
position/pixel across the screen, you must use an additional POKE (V+16)
which sets the most significant bit of the X position and start counting
from 0 again at the 256th pixel across the screen.
This POKE starts the X numbering over again from 0 at the 256th position
(Example: POKE V+16,PEEK(V+16)OR 1 and POKE V,1 must be included to place
sprite 0 at the 257th pixel across the screen.) To get back to the left
side X positions you have to TURN OFF the control setting by typing
POKE V+16,PEEK(V+16)AND 254.
This line POKEs V+ 16 with the number required to "open up" the right
side of the screen... the new X position 24 for sprite 0 now begins 24
pixels to the RIGHT of position 255. To check the right edge of the
screen, change line 60 to:
Some experimentation with the settings in the sprite chart will give
you the settings you need to position and move sprites on the left and
right sides of the screen. The section on "moving sprites" will also
increase your understanding of how sprite positioning works.
SPRITE PRIORITIES
DRAWING A SPRITE
Each little "square" represents one pixel in the sprite. There are 24
pixels across and 21 pixels up and down, or 504 pixels in the entire
sprite. To make the sprite look like something, you have to color in
these pixels using a special PROGRAM... but how can you control over 500
individual pixels? That's where computer programming can help you. In-
stead of typing 504 separate numbers, you only have to type 63 numbers
for each sprite. Here's how it works...
162 PROGRAMMING GRAPHICS
~
To make this as easy as possible for you, we've put together this
simple step by step guide to help you draw your own sprites.
STEP 1:
STEP 2:
Color in the pixels on the spritemaking grid on Page 162 (or use a piece
of graph paper... remember, a sprite has 24 squares across and 21 squares
down). We suggest you use a pencil and draw lightly so you can reuse this
grid. You can create any image you like, but for our example we'll draw
a simple box.
STEP 3:
Look at the first EIGHT pixels. Each column of pixels has a number (128,
64, 32, 16, 8, 4, 2, 1). The special type of addition we are going to
show you is a type of BINARY ARITHMETIC which is used by most computers
Add up the numbers of the SOLID pixels. This first group of eight pixels
is completely solid, so the total number is 255.
STEP 5:
Enter that number as the FIRST DATA STATEMENT in line 100 of the
Spritemaking Program below. Enter 255 for the second and third groups
of eight.
STEP 6:
Look at the FIRST EIGHT PIXELS IN THE SECOND ROW of the sprite. Add up
the values of the solid pixels. Since only one of these pixels is solid,
the total value is 128. Enter this as the first DATA number in line 101.
Add up the values of the next group of eight pixels (which is 0 because
they're all BLANK) and enter in line 101. Now move to the next group of
pixels and repeat the process for each GROUP OF EIGHT PIXELS (there are
3 groups across each row, and 21 rows). This will give you a total of 63
numbers. Each number represents ONE group of 8 pixels, and 63 groups of
eight equals 504 total individual pixels. Perhaps a better way of looking
at the program is like this... each line in the program represents ONE
ROW in the sprite. Each of the 3 numbers in each row represents ONE GROUP
OF EIGHT PIXELS. And each number tells the computer which pixels to make
SOLID and which pixels to leave blank.
STEP 8:
CRUNCH YOUR PROGRAM INTO A SMALLER SPACE BY RUNNING TOGETHER ALL THE DATA
STATEMENTS, AS SHOWN IN THE SAMPLE PROGRAM BELOW. Note that we asked you
to write your sprite program on a piece of paper. We did this for a good
reason. The DATA STATEMENT LINES 100-120 in the program in STEP 1 are
only there to help you see which numbers relate to which groups of pixels
in your sprite. Your final program should be "crunched" like this:
Now that you've created your sprite, let's do some interesting things
with it. To move your sprite smoothly across the screen, add these two
lines to your program:
LINE 55 has a FOR... NEXT loop which continues to POKE the sprite in
the last 65 positions on the screen. Note that the X value was reset to
zero but because you used the RIGHT X setting (POKE V+16,2) X starts over
on the right side of the screen.
This line keeps going back to itself (GOTO 50). If you just want the
sprite to move ONCE across the screen and disappear, then take out
GOTO50.
Do you see how these programs work? This program is the same as the
previous one, except when it reaches the end of the right side of the
screen, it REVERSES ITSELF and goes back in the other direction. That is
what the STEP-1 accomplishes... it tells the program to POKE the sprite
into X values from 65 to 0 on the right side of the screen, then from 255
to 0 on the left side of the screen, STEPping backwards minus-1 position
at a time.
VERTICAL SCROLLING
50 <RETURN>
60 <RETURN>
LINE 5:
LINE 15:
LINE 20:
NEXT This tells the computer to look BETWEEN the FOR and
NEXT parts of the loop and perform those in-between
commands (READQ1 and POKES1,Q1 using the NEXT
numbers in order). In other words, the NEXT
statement makes the computer READ the NEXT Q1 from
the DATA STATEMENTS, which is 0, and also
increments S1 by 1 to the next value, which is
12289. The result is POKE12289,0... the NEXT
command makes the loop keep going back until the
last values in the series, which are POKE 12350,0.
LINE 25:
POKES2,Q2 Pokes the data (Q2) into the memory locations (S2)
for our second sprite shape, which begins at
location 12352.
LINE 30:
LINE 35:
LINE 40:
{light blue} This sets the color back to light blue when the
PRINT statement ends. Holding down <C=> and <7>
a at the same time inside quotation marks
causes a "reversed diamond symbol" to appear.
LINE 45:
LINE 50:
LINE 55:
LINE 60:
LINE 70:
LINE 75:
LINE 80:
LINE 85:
LINE 95
LINES 100-109
DATA The sprite shapes are read from the data numbers,
in order. First the 63 numbers which comprise
sprite shape 1 are read, then the 63 numbers for
sprite shape 2, and then sprite shape 3. This data
is permanently read into the 3 memory locations and
after it is read into these locations, all the
program has to do is point sprite 0 at the 3 memory
locations and the sprite automatically takes the
shape of the data in those locations. We are
pointing the sprite at 3 locations one at a time
which produces the "animation" effect. If you want
to see how these numbers affect each sprite, try
changing the first 3 numbers in LINE 100 to 255,
255, 255. See the section on defining sprite shapes
for more information.
LINE 200:
LINE 300:
POKES+11,129 Waveform control set to 129 turns on the sound
effect.
POKES+11,128 Waveform control set to 128 turns off the sound
effect.
RETURN Sends program back to end of line 75 to resume.
SPRITEMAKING NOTES
You can turn on any individual sprite by using POKE V+21 and the number
from the chart... BUT... turning on just ONE sprite will turn OFF any
others. To turn on TWO OR MORE sprites, ADD TOGETHER the numbers of the
sprites you want to turn on (Example: POKE V+21, 6 turns on sprites 1 and
2). Here is a method you can use to turn one sprite off and on without
affecting any of the others (useful for animation).
EXAMPLE:
X positions run from 0 to 255... and then START OVER from 0 to 255. To
put a sprite beyond X position 255 on the far right side of the screen,
you must first POKE V+ 16 as shown, THEN POKE a new X valve from 0 to 63,
which will place the sprite in one of the X positions at the right side
of the screen. To get back to positions 0-255, POKE V+16,0 and POKE in an
X value from 0 to 255.
Y POSITION VALUES:
SPRITE COLORS:
To make sprite 0 WHITE, type: POKE V+39,1 (use COLOR POKE SETTING shown
in chart, and INDIVIDUAL COLOR CODES shown below):
MEMORY LOCATION:
PRIORITY:
Priority means one sprite will appear to move "in front of" or "behind"
another sprite on the display screen. Sprites with more priority always
appear to move "in front of" or "on top of" sprites with less priority.
The rule is that lower numbered sprites have priority over higher
numbered sprites. Sprite 0 has priority over all other sprites. Sprite 7
has no priority in relation to the other sprites. Sprite 1 has priority
over sprites 2-7, etc. If you put two sprites in the some position, the
sprite with the higher priority will appear IN FRONT OF the sprite with
the lower priority. The sprite with lower priority will either be
obscured, or will "show through" (from "behind") the sprite with higher
priority.
USING MULTI-COLOR:
+-+-+
| | | BACKGROUND (Making BOTH PIXELS BLANK (zero) lets the
+-+-+ INNER SCREEN COLOR (background)show through.)
+-+-+
| |@| MULTI-COLOR 1 (Making the RIGHT PIXEL SOLID in a pair of pixels
+-+-+ sets BOTH PIXELS to Multi-Color 1.)
+-+-+
|@| | SPRITE COLOR (Making the LEFT PIXEL SOLID in a pair of pixels
+-+-+ sets BOTH PIXELS to Sprite Color.)
+-+-+
|@|@| MULTI-COLOR 2 (Making BOTH PIXELS SOLID in a pair of pixels
+-+-+ sets BOTH PIXELS to Multi-Color 2.)
Look at the horizontal 8-pixel row shown below. This block sets the first
two pixels to background color, the second two pixels to Multi-Color 1,
the third two pixels to Sprite Color and the fourth two pixels to Multi-
Color 2. The color of each PAIR of pixels depends on which bits in each
pair are solid and which are blank, according to the illustration above.
After you determine which colors you want in each pair of pixels, the
next step is to add the values of the solid pixels in the 8-pixel block,
and POKE that number into the proper memory location. For example, if the
8-pixel row shown below is the first block in a sprite which begins at
memory location 832, the value of the solid pixels is 16+8+2+1 27, so you
would POKE 832,27.
+-------+-------+-------+-------+
|BACKGR.|MULTI- |SPRITE |MULTI- |
| COLOR |COLOR 1| COLOR |COLOR 2|
+-------+-------+-------+-------+
COLLISION:
You can detect whether a sprite has collided with another sprite by
using this line: IF PEEK(V+30)ANDX=XTHEN [insert action here]. This line
checks to see if a particular sprite has collided with ANY OTHER SPRITE,
where X equals 1 for sprite 0, 2 for sprite 1, 4 for sprite 2, 8 for
sprite 3, 16 for sprite 4, 32 for sprite 5, 64 for sprite 6, and 128 for
sprite 7. To check to see if the sprite has collided with a "BACKGROUND
CHARACTER" use this line: IF PEEK(V+31)ANDX=XTHEN [insert action here].
The following program allows you to create a sprite using blanks and
solid circles <SHIFT+Q> in DATA statements. The sprite and the numbers
POKED into the sprite data registers are displayed.
CHAPTER 4
PROGRAMMING
SOUND AND
MUSIC ON YOUR
COMMODORE 64
o Introduction
Volume Control
Frequencies of Sound Waves
o Using Multiple Voices
o Changing Waveforms
o The Envelope Generator
o Filtering
o Advanced Techniques
o Synchronization and Ring
Modulation
183
~
INTRODUCTION
POKE MEM,NUM
The memory locations (MEM) used for music synthesis start at 54272
($D400) in the Commodore 64. The memory locations 54272 to 54296
inclusive are the POKE locations you need to remember when you're using
the 6581 (SID) chip register map. Another way to use the locations above
is to remember only location 54272 and then add a number from 0 through
24 to it. By doing this you can POKE all the locations from 54272 to
54296 that you need from the SID chip. The numbers (NUM) that you use in
your POKE statement must be between 0 and 255, inclusive.
184 PROGRAMMING SOUND AND MUSIC
~
When you've had a little more practice with making music, then you can
get a little more involved, by using the PEEK function. PEEK is a
function that is equal to the value currently in the indicated memory
location.
X=PEEK(MEM)
EXAMPLE PROGRAM 1:
start tok64 page185.prg
5 s=54272
10 forl=stos+24:pokel,0:next:rem clear sound chip
20 pokes+5,9:pokes+6,0
30 pokes+24,15 :rem set volume to maximum
40 readhf,lf,dr
50 ifhf<0thenend
60 pokes+1,hf:pokes,lf
70 pokes+4,33
80 fort=1todr:next
90 pokes+4,32:fort=1to50:next
100 goto40
110 data25,177,250,28,214,250
120 data25,177,250,25,177,250
130 data25,177,125,28,214,125
140 data32,94,750,25,177,250
150 data28,214,250,19,63,250
160 data19,63,250,19,63,250
170 data21,154,63,24,63,63
180 data25,177,250,24,63,125
190 data19,63,250,-1,-1,-1
stop tok64
+--------+--------------------------------------------------------------+
| Line(s)| Description |
+--------+--------------------------------------------------------------+
| 5 | Set S to start of sound chip. |
| 10 | Clear all sound chip registers. |
| 20 | Set Attack/Decay for voice 1 (A=O,D=9). |
| | Set Sustain/Release for voice 1 (S=O,R=O), |
| 30 | Set volume at maximum. |
| 40 | Read high frequency, low frequency, duration of note. |
| 50 | When high frequency less than zero, song is over. |
| 60 | Poke high and low frequency of voice 1. |
| 70 | Gate sawtooth waveform for voice 1. |
| 80 | Timing loop for duration of note. |
| 90 | Release sawtooth waveform for voice 1. |
| 100 | Return for next note. |
| 110-180| Data for song: high frequency, low frequency, duration |
| | (number of counts) for each note. |
| 190 | Last note of song and negative Is signaling end of song. |
+--------+--------------------------------------------------------------+
VOLUME CONTROL
Chip register 24 contains the overall volume control. The volume can be
set anywhere between 0 and 15. The other four bits are used for purposes
we'll get into later. For now it is enough to know volume is 0 to 15.
Look at line 30 to see how it's set in Example Program 1.
frequency other than the ones listed in the note table use "Fout" (fre-
quency output) and the following formula to represent the frequency (Fn)
of the sound you want to create. Remember that each note requires both a
high and a low frequency number.
Fn = Fout/.06097
Once you've figured out what Fn is for your "new" note the next step is
to create the high and low frequency values for that note. To do this you
must first round off Fn so that any numbers to the right of the decimal
point are left off. You are now left with an integer value. Now you can
set the high frequency location (Fhi) by using the formula
Fhi=INT(Fn/256) and the low frequency location (Flo) should be
Flo=Fn-(256*Fhi).
At this point you have already played with one voice of your computer.
If you wanted to stop here you could find a copy of your favorite tune
and become the maestro conducting your own computer orchestra in your "at
home" concert hall.
EXAMPLE PROGRAM 2:
130 ifnm=0then250
140 wa=v(k):wb=wa-1:ifnm<0thennm=-nm:wa=0:wb=0
150 dr%nm/128:oc%=(nm-128*dr%)/16
160 nt=nm-128*dr%-16*oc%
170 fr=fq(nt)
180 ifoc%=7then200
190 forj=6tooc%step-1:fr=fr/2:next
200 hf%=fr/256:lf%=fr-256*hf%
210 ifdr%=1thenh(k,i)=hf%:l(k,i)=lf%:c(k,i)=wa:i=i+1:goto120
220 forj=1todr%-1:h(k,i)=hf%:l(k,i)=lf%:c(k,i)=wa:i=i+1:next
230 h(k,i)=hf%:l(k,i)=lf%:c(k,i)=wb
240 i=i+1:goto120
250 ifi>imthenim=i
260 next
500 pokes+5,0:pokes+6,240
510 pokes+12,85:pokes+13,133
520 pokes+19,10:pokes+20,197
530 pokes+24,31
540 fori=0toim
550 pokes,l(0,i):pokes+7,l(1,i):pokes+14,l(2,i)
560 pokes+1,h(0,i):pokes+8,h(1,i):pokes+15,h(2,i)
570 pokes+4,c(0,i):pokes+11,c(1,i):pokes+18,c(2,i)
580 fort=1to80:next:next
590 fort=1to200:next:pokes+24,0
600 data34334,36376,38539,40830
610 data43258,45830,48556,51443
620 data54502,57743,61176,64814
1000 data594,594,594,596,596,1618,587,592,587.585,331,336
1010 data1097,583,585,585,585,587,587,1609,585,331,337,594,594,593
1020 data1618,594,596,594,592,587,1616,587,585,331,336,841,327
1999 data1607,0
2000 data583,585,583,583,327,329,1611,583,585,578,578,578
2010 data196,198,583,326,578,326,327,329,327,329,326,578,583
2020 data1606,582,322,324,582,587,329,327,1606,583,327,329,587,331,329
2999 data329,328,1609,578,834,324,322,327,585,1602,0
3000 data567,566,567,304,306,308,310,1591,567,311,310,567
3010 data306,304,299,308,304,171,176,306,291,551,306,308
3020 data310,308,310,306,295,297,299,304,1586,562,567,310,315,311
3030 data308,313,297,1586,567,560,311,309,308,309,306,308
3999 data1577,299,295,306,310,311,304,562,546,1575,0
stop tok64
+---------+-------------------------------------------------------------+
| Line(s) | Description |
+---------+-------------------------------------------------------------+
| 10 | Set S equal to start of sound chip and clear all sound |
| | chip registers. |
| 20 | Dimension arrays to contain activity of song, 1/16th of a |
| | measure per location. |
| 30 | Dimension array to contain base frequency for each note. |
| 40 | Store waveform control byte for each voice. |
| 50 | Set high pulse width for voice 2. |
| | Set high frequency for filter cutoff. |
| | Set resonance for filter and filter voice 3. |
| 60 | Read in base frequency for each note. |
| 100 | Begin decoding loop for each voice. |
| 110 | Initialize pointer to activity array. |
| 120 | Read coded note. |
| 130 | If coded note is zero, then next voice. |
| 140 | Set waveform controls to proper voice. |
| | If silence, set waveform controls to 0. |
| 150 | Decode duration and octave. |
| 160 | Decode note. |
| 170 | Get base frequency for this note. |
| 180 | If highest octave, skip division loop. |
| 190 | Divide base frequency by 2 appropriate number of times. |
| 200 | Get high and low frequency bytes. |
| 210 | If sixteenth note, set activity array: high frequency, low |
| | frequency, and waveform control (voice on). |
| 220 | For all but last beat of note, set activity array: high |
| | frequency, low frequency, waveform control (voice on). |
| 230 | For last beat of note, set activity array: high frequency, |
| | low frequency, waveform control (voice off). |
| 240 | Increment pointer to activity array. Get next note. |
| 250 | If longer than before, reset number of activities. |
| 260 | Go back for next voice. |
| 500 | Set Attack/Decay for voice 1 (A=0, D=0). |
| | Set Sustain/Release for voice 1 (S=15, R=0). |
+---------+-------------------------------------------------------------+
| Line(s) | Description |
+---------+-------------------------------------------------------------+
| 510 | Set Attack/Decay for voice 2 (A=5, D=5). |
| | Set Sustain/Release for voice 2 (S=8, R=5). |
| 520 | Set Attack/Decay for voice 3 (A=O, D=10). |
| | Set Sustain/Release for voice 3 (S=12, R=5). |
| 530 | Set volume 15, low-pass filtering. |
| 540 | Start loop for every 1/16th of a measure. |
| 550 | POKE low frequency from activity array for all voices. |
| 560 | POKE high frequency from activity array for all voices. |
| 570 | POKE waveform control from activity array for all voices. |
| 580 | Timing loop for 1/16th of a measure and back for next |
| | 1/16th measure. |
| 590 | Pause, then turn off volume. |
| 600-620 | Base frequency data. |
|1000-1999| Voice 1 data. |
|2000-2999| Voice 2 data. |
|3000-3999| Voice 3 data. |
+-----------------------------------------------------------------------+
The values used in the data statements were found by using the note
table in Appendix E and the chart below:
+-----------------+------------+
| NOTE TYPE | DURATION |
+-----------------+------------+
| 1/16 | 128 |
| 1/8 | 256 |
| DOTTED 1/8 | 384 |
| 1/4 | 512 |
| 1/4+1/16 | 640 |
| DOTTED 1/4 | 768 |
| 1/2 | 1024 |
| 1/2+1/16 | 1152 |
| 1/2+1/8 | 1280 |
| DOTTED 1/2 | 1536 |
| WHOLE | 2048 |
+-----------------+------------+
The note number from the note table is added to the duration above.
Then each note can be entered using only one number which is decoded by
your program. This is only one method of coding note values. You may be
able to come up with one with which you are more comfortable. The formula
used here for encoding a note is as follows:
In other words:
((((D*8)+O)*16)+N)
Once you have gotten used to using more than one voice, you will find
that the timing of the three voices needs to be coordinated. This is ac-
complished in this program by:
The high and low frequency bytes are calculated by dividing the fre-
quencies of the highest octave by two (lines 180 and 190). The waveform
control byte is a start signal for beginning a note or continuing a note
that is already playing. It is a stop signal to end a note. The waveform
choice is made once for each voice in line 40.
Again, this is only one way to control multiple voices. You may come
up with your own methods. However, you should now be able to take any
piece of sheet music and figure out the notes for all three voices.
CHANGING WAVEFORMS
+ +
+ + + +
/ \ / \
./.......\......./.......\.
\ /
+ +
+
To make what we're talking about a bit more practical, let's go back to
the first example program to investigate different waveforms. The reason
for this is that you can hear the changes more easily using only one
voice. LOAD the first music program that you typed in earlier, from your
DATASSETTE(TM) or disk, and RUN it again. That program is using the
sawtooth waveform (shown here)
+ + +
/| /| /|
/ | / | / |
/ | / | / |
./...|.../...|.../...|.....
| / | / | /
| / | / | /
|/ |/ |/
+ + +
from the 6581 SID chip's sound generating device. Try changing the note
start number in line 70 from 33 to 17 and the note stop number in line 90
from 32 to 16. Your program should now look like this:
PWout = (PWn/40.95) %
When PWn has a value of 2048, it will give you a square wave. That
means that register 2 (Lpw) = 0 and register 3 (Hpw) = 8.
Now try adding this line to your program:
15 POKES+3,8:POKES+2,0
Then change the start number in line 70 to 65 and the stop number in fine
90 to 64, and RUN the program. Now change the high pulse width (register
3 in line 15) from an 8 to a 1. Notice how dramatic the difference in
sound quality is?
The last waveform available to you is white noise (shown here).
. . .
. . . . .
. . . .
...........................
. . . .
. . . .
. . .
It is used mostly for sound effects and such. To hear how it sounds, try
changing the start number in line 70 to 129 and the stop number in line
90 to 128.
UNDERSTANDING WAVEFORMS
The volume of a musical tone changes from the moment you first hear it,
all the way through until it dies out and you can't hear it anymore. When
a note is first struck, it rises from zero volume to its peak volume. The
rate at which this happens is called the ATTACK. Then, it fails from the
peak to some middle-ranged volume. The rate at which the fall of the note
occurs is called the DECAY. The mid-ranged volume itself is called the
SUSTAIN level. And finally, when the note stops playing, it fails from
the SUSTAIN level to zero volume. The rate at which it fails is called
the RELEASE. Here is a sketch of the four phases of a note:
+
/ \
/ \
/ \
SUSTAIN LEVEL . ./. . . .+--------+
/ \
/ \
/ \
| | | | |
| A | D | S | R |
Each of the items mentioned above give certain qualities and restric-
tions to a note. The bounds are called parameters.
The parameters ATTACK/DECAY/SUSTAIN/RELEASE and collectively called
ADSR, can be controlled by your use of another set of locations in the
sound generator chip. LOAD your first example program again. RUN it again
and remember how it sounds. Then, changing line 20 so the program is like
this:
Registers 5 and 6 define the ADSR for voice 1. The ATTACK is the high
nybble of register 5. Nybble is half a byte, in other words the lower 4
or higher 4 on/off locations (bits) in each register. DECAY is the low
nybble. You can pick any number 0 through 15 for ATTACK, multiply it by
16 and add to any number 0 through 15 for DECAY. The values that
correspond to these numbers are listed below.
SUSTAIN level is the high nybble of register 6. It can be 0 through 15.
It defines the proportion of the peak volume that the SUSTAIN level will
be. RELEASE rate is the low nybble of register 6.
Here are the meanings of the values for ATTACK, DECAY, and RELEASE:
+-----+------------------------+--------------------------------+
|VALUE|ATTACK RATE (TIME/CYCLE)| DECAY/RELEASE RATE (TIME/CYCLE)|
+-----+------------------------+--------------------------------+
| 0 | 2 ms | 6 ms |
| 1 | 8 ms | 24 ms |
| 2 | 16 ms | 48 ms |
| 3 | 24 ms | 72 ms |
| 4 | 38 ms | 114 ms |
| 5 | 56 ms | 168 ms |
| 6 | 68 ms | 204 ms |
| 7 | 80 ms | 240 ms |
| 8 | 100 ms | 300 ms |
| 9 | 250 ms | 750 ms |
| 10 | 500 ms | 1.5 s |
| 11 | 800 ms | 2.4 s |
| 12 | 1 s | 3 s |
| 13 | 3 s | 9 s |
| 14 | 5 s | 15 s |
| 15 | 8 s | 24 s |
+-----+------------------------+--------------------------------+
Here are a few sample settings to try in your example program. Try
these and a few of your own. The variety of sounds you can produce is
astounding! For a violin type sound, try changing line 20 to read:
20 POKES+5,88:POKES+6,89:REM A=5;D=8;S=5;R=9
Change the waveform to triangle and get a xylophone type sound by using
these lines:
20 POKES+5,9:POKES+6,9:REM A=0;D=9;S=O;R=9
70 POKES+4,17
90 POKES+4,16:FORT=1TO50:NEXT
Change the waveform to square and try a piano type sound with these
lines:
15 POKES+3,8:POKES+2,0
20 POKES+5,9:POKES+6,0: REM A=0;D=9;S=0;R=0
70 POKES+4,65
90 POKES+4,64:FORT=1TO50:NEXT
The most exciting sounds are those unique to the music synthesizer
itself, ones that do not attempt to mimic acoustic instruments. For
example try:
FILTERING
Try RUNning the program now. Notice the lower tones have had their
volume cut down. It makes the overall quality of the note sound tinny.
This is because you are using a high-pass filter which attenuates (cuts
down the level of) frequencies below the specified cutoff frequency.
There are three types of filters in your Commodore computer's SID chip.
We have been using the high-pass filter. It will pass all the frequencies
at or above the cutoff, while attenuating the frequencies below the
cutoff.
|
AMOUNT | +-----
PASSED | /
| /
| /
+------|-------
FREQUENCY
200 PROGRAMMING SOUND AND MUSIC
~
The SID chip also has a low-pass filter. As its name implies, this
filter will pass the frequencies below cutoff and attenuate those above.
|
AMOUNT | -----+
PASSED | \
| \
| \
+------|-------
FREQUENCY
|
AMOUNT | +
PASSED | / \
| / \
| / \
+------|-------
FREQUENCY
The high- and low-pass filters can be combined to form a notch reject
filter which passes frequencies away from the cutoff while attenuating
at the cutoff frequency.
|
AMOUNT | --+ +---
PASSED | \ /
| \ /
| +
+------|-------
FREQUENCY
ADVANCED TECHNIQUES
EXAMPLE PROGRAM 6:
+----------+------------------------------------------------------------+
| Lines(s) | Description |
+----------+------------------------------------------------------------+
| 10 | Set S to beginning of sound chip. |
| 20 | Clear all sound chip locations. |
| 30 | Set high pulse width for voice 1. |
| 40 | Set Attack/Decay for voice 1 (A=2, D=9). |
| | Set Sustain/Release for voice 1 (S=5, R=9). |
| 50 | Set low frequency for voice 3. |
| 60 | Set triangle waveform for voice 3. |
| 70 | Set volume 15, turn off audio output of voice 3. |
| 80 | Read frequency and duration of note. |
| 90 | If frequency equals zero, stop. |
| 100 | POKE start pulse waveform control voice 1. |
| 110 | Start timing loop for duration. |
| 120 | Get new frequency using oscillator 3 output. |
| 130 | Get high and low frequency. |
| 140 | POKE high and low frequency for voice 1. |
| 150 | End of timing loop. |
| 160 | POKE stop pulse waveform control voice 1. |
| 170 | Go back for next note. |
| 500-550 | Frequencies and durations for song, |
| 560 | Zeros signal end of song. |
+----------+------------------------------------------------------------+
A wide variety of sound effects can also be achieved using dynamic
effects. For example, the following siren program dynamically changes the
frequency output of oscillator 1 when it's based on the output of
oscillator 3's triangular wave:
EXAMPLE PROGRAM 7:
+---------+-------------------------------------------------------------+
| Line(s) | Description |
+---------+-------------------------------------------------------------+
| 10 | Set S to start of sound chip. |
| 20 | Clear sound chip registers. |
| 30 | Set low frequency of voice 3. |
| 40 | Set triangular waveform voice 3. |
| 50 | Set high pulse width for voice 1. |
| 60 | Set volume 15, turn off audio output of voice 3. |
| 70 | Set Sustain/Release for voice I (S=15, R=0). |
| 80 | POKE start pulse waveform control voice 1. |
| 90 | Set lowest frequency for siren. |
| 100 | Begin timing loop. |
| 110 | Get new frequency using output of oscillator 3. |
| 120 | Get high and low frequencies. |
| 130 | POKE high.and low frequencies for voice 1. |
| 140 | End timing loop. |
| 150 | Turn off volume. |
+---------+-------------------------------------------------------------+
EXAMPLE PROGRAM 8:
+---------+-------------------------------------------------------------+
| Line(s) | Description |
+---------+-------------------------------------------------------------+
| 10 | Set S to start of sound chip. |
| 20 | Clear all sound chip registers. |
| 30 | Set high and low frequencies for voice 1. |
| 40 | Set Attack/Decay for voice I (A=0, D=8). |
| 50 | Set high cutoff frequency for filter. |
| 60 | Turn on filter for voice 1. |
| 70 | Set volume 15, high-pass filter. |
| 80 | Count 15 claps. |
| 90 | Set start noise waveform control. |
| 100 | Wait, then set stop noise waveform control. |
| 110 | Wait, then start next clap- |
| 120 | Turn off volume. |
+---------+-------------------------------------------------------------+
The 6581 SID chip lets you create more complex harmonic structures
through synchronization or ring modulation of two voices.
The process of synchronization is basically a logical ANDing of two
wave forms. When either is zero, the output is zero. The following
example uses this process to create an imitation of a mosquito:
EXAMPLE PROGRAM 9:
CHAPTER 5
BASIC TO
MACHINE
LANGUAGE
209
~
READY.
The OPERATING SYSTEM of the Commodore 64 then allows you to type on the
keyboard, and use the built-in SCREEN EDITOR on the Commodore 64. The
SCREEN EDITOR allows you to move the cursor, DELete, INSert, etc., and
is, in fact, only one part of the operating system that is built in for
your convenience.
All of the commands that are available in CBM BASIC are simply
recognized by another huge machine language program built into your
Commodore 64. This huge program "RUNS" the appropriate piece of machine
language depending on which CBM BASIC command is being executed. This
program is called the BASIC INTERPRETER, because it interprets each
command, one by one, unless it encounters a command it does not
understand, and then the familiar message appears:
?SYNTAX ERROR
READY.
You should be familiar with the PEEK and POKE commands in the CBM BASIC
language for changing memory locations. You've probably used them for
graphics on the screen, and for sound effects. Each memory location has
its own number which identifies it. This number is known as the "address"
of a memory location. If you imagine the memory in the Commodore 64 as a
street of buildings, then the number on each door is, of course, the
address. Now let's look at which parts of the street are used for what
purposes.
THE ACCUMULATOR
This register contains the location of the first empty place on the
stack. The stack is used for temporary storage by machine language pro-
grams, and by the computer.
programs, you must use either a program to do this, or write for yourself
a BASIC program that "allows" you to write machine language.
The most common methods used to write machine language programs are
assembler programs. These packages allow you to write machine language
instructions in a standardized mnemonic format, which makes the machine
language program a lot more readable than a stream of numbers! Let's
review: A program that allows you to write machine language programs in
mnemonic format is called an assembler. Incidentally, a program that
displays a machine language program in mnemonic format is called a
disassembler. Available for your Commodore 64 is a machine language
monitor cartridge (with assembler/disassembler, etc.) made by Commodore:
64MON
The 64MON cartridge available from your local dealer, is a program that
allows you to escape from the world of CBM BASIC, into the land of
machine language. It can display the contents of the internal registers
in the 6510 microprocessor, and it allows you to display portions of mem-
ory, and change them on the screen, using the screen editor. It also has
a built-in assembler and disassembler, as well as many other features
that allow you to write and edit machine language programs easily. You
don't HAVE to use an assembler to write machine language, but the task is
considerably easier with it. If you wish to write machine language
programs, it is strongly suggested that you purchase an assembler of some
sort. Without an assembler you will probably have to "POKE" the machine
language program into memory, which is totally unadvisable. This manual
will give its examples in the format that 64MON uses, from now on. Nearly
all assembler formats are the same, therefore the machine language
examples shown will almost certainly be compatible with any assembler.
But before explaining any of the other features of 64MON, the hexadecimal
numbering system must be explained.
HEXADECIMAL NOTATION
(base 16) (or just "hex" as most people say). These assemblers do the
conversions for you.
Hexadecimal probably seems a little hard to grasp at first, but like
most things, it won't take long to master with practice.
By looking at decimal (base 10) numbers, you can see that each digit
fails somewhere in the range between zero and a number equal to the base
less one (e.g., 9). THIS IS TRUE OF ALL NUMBER BASES. Binary (base 2)
numbers have digits ranging from zero to one (which is one less than the
base). Similarly, hexadecimal numbers should have digits ranging from
zero to fifteen, but we do not have any single digit figures for the
numbers ten to fifteen, so the first six letters of the alphabet are used
instead:
+---------+-------------+----------+
| DECIMAL | HEXADECIMAL | BINARY |
+---------+-------------+----------+
| 0 | 0 | 00000000 |
| 1 | 1 | 00000001 |
| 2 | 2 | 00000010 |
| 3 | 3 | 00000011 |
| 4 | 4 | 00000100 |
| 5 | 5 | 00000101 |
| 6 | 6 | 00000110 |
| 7 | 7 | 00000111 |
| 8 | 8 | 00001000 |
| 9 | 9 | 00001001 |
| 10 | A | 00001010 |
| 11 | B | 00001011 |
| 12 | C | 00001100 |
| 13 | D | 00001101 |
| 14 | E | 00001110 |
| 15 | F | 00001111 |
| 16 | 10 | 00010000 |
+---------+-------------+----------+
Base raised by
increasing powers:... 10^3 10^2 10^1 10^0
---------------------
Equals:.............. 1000 100 10 1
---------------------
Base raised by
increasing powers:... 16^3 16^2 16^1 16^0
---------------------
Equals:.............. 4096 256 16 1
---------------------
you will see rows of 9 hex numbers. The first 4-digit number is the ad-
dress of the first byte of memory being shown in that row, and the other
eight numbers are the actual contents of the memory locations beginning
at that start address.
BASIC TO MACHINE LANGUAGE 217
~
You should really try to learn to "think" in hexadecimal. It's not too
difficult, because you don't have to think about converting it back into
decimal. For example, if you said that a particular value is stored at
$14ED instead of 5357, it shouldn't make any difference.
This instruction will put $05 (decimal 5) into the accumulator register.
The assembler will put into the specified address for this instruction,
$A9 (which is the token for this particular instruction, in this mode),
and it will put $05 into the next location after the location containing
the instruction ($A9).
If the parameter to be used by an instruction has "#" before it; i.e.,
the parameter is a "value," rather than the contents of a memory loca-
tion, or another register, the instruction is said to be in the
"immediate" mode. To put this into perspective, let's compare this with
another mode:
If you want to put the contents of memory location $102E into the
accumulator, you're using the "absolute" mode of instruction:
LDA $102E
The assembler can distinguish between the two different modes because the
latter does not have a "#" before the parameter. The 6510 microprocessor
can distinguish between the immediate mode, and the absolute mode of the
LDA instruction, because they have slightly different tokens. LDA
(immediate) has $A9 as its token, and LDA (absolute), has $AD as its
token.
The mnemonic representing an instruction usually implies what it does.
For instance, if we consider another instruction, LDX, what do you think
this does?
If you said "load the X register with...", go to the top of the class.
If you didn't, then don't worry, learning machine language does take
patience, and cannot be learned in a day.
The various internal registers can be thought of as special memory
locations, because they too can hold one byte of information. It is not
necessary for us to explain the binary numbering system (base 2) since it
follows the same rules as outlined for hexadecimal and decimal outlined
previously, but one "bit" is one binary digit and eight bits make up one
byte! This means that the maximum number that can be contained in a
byte is the largest number that an eight digit binary number can be. This
number is 11111111 (binary), which equals $FF (hexadecimal), which equals
255 (decimal). You have probably wondered why only numbers from zero to
255 could be put into a memory location. If you try POKE 7680,260 (which
is a BASIC statement that "says": "Put the number two hundred and sixty,
into memory location seven thousand, six hundred and eighty", the BASIC
interpreter knows that only numbers 0 - 255 can be put in a memory
location, and your Commodore 64 will reply with:
READY.
If the limit of one byte is $FF (hex), how is the address parameter in
the absolute instruction "LDA $102E" expressed in memory? It's expressed
in two bytes (it won't fit into one, of course). The lower (rightmost)
two digits of the hexadecimal address form the "low byte" of the address,
and the upper (leftmost) two digits form the "high byte."
The 6510 requires any address to be specified with its low byte first,
and then the high byte. This means that the instruction "LDA $102E" is
represented in memory by the three consecutive values:
Now all you need to know is one more instruction and then you can write
your first program. That instruction is BRK. For a full explanation of
If you've used the POKE statement in BASIC to put characters onto the
screen, you're aware that the character codes for POKEing are different
from CBM ASCII character values. For example, if you enter:
65
READY.
However, to put an "A" onto the screen by POKEing, the code is 1, enter:
Type:
.A 1405
G 1400
The G should turn into an "A" if you've done everything correctly. You
have now written your first machine language program. Its purpose is to
store one character ("A") at the first location in the screen memory.
Having achieved this, we must now explore some of the other instructions,
and principles.
ADDRESSING MODES
ZERO PAGE
THE STACK
+-----------------------------------------------------------------------+
| NOTE: The X register will be referred to as X from now on, and |
| similarly A (accumulator), Y (Y index register), S (stack pointer), |
| and P (processor status). |
+-----------------------------------------------------------------------+
INDEXING
EXAMPLE:
LDA $9000,X
There are absolute indexed, zero page indexed, indirect indexed, and
indexed indirect modes of addressing available on the 6510
microprocessor.
INDIRECT INDEXED
This only allows usage of the Y register as the index. The actual ad-
dress can only be in zero page, and the mode of instruction is called
indirect because the zero page address specified in the instruction con-
tains the low byte of the actual address, and the next byte to it
contains the high order byte.
EXAMPLE:
Let us suppose that location $02 contains $45, and location $03 con-
tains $1E. If the instruction to load the accumulator in the indirect
indexed mode is executed and the specified zero page address is $02, then
the actual address will be:
INDEXED INDIRECT
Indexed indirect only allows usage of the X register as the index. This
is the some as indirect indexed, except it is the zero page address of
the pointer that is indexed, rather than the actual base address.
Therefore, the actual base address IS the actual address because the
index has already been used for the indirect. Index indirect would also
be used if a table of indirect pointers were located in zero page memory,
and the X register could then specify which indirect pointer to use.
EXAMPLE:
Let us suppose that location $02 contains $45, and location $03 con-
tains $10. If the instruction to load the accumulator in the indexed
indirect mode is executed and the specified zero page address is $02,
then the actual address will be:
LDA #$00
will cause the zero result flag to be set, because the instruction has
resulted in the accumulator containing a zero.
There are a set of instructions that will, given a particular
condition, branch to another part of the program. An example of a branch
instruction is BEQ, which means Branch if result EQual to zero. The
branch instructions branch if the condition is true, and if not, the
program continues onto the next instruction, as if nothing had occurred.
The branch instructions branch not by the result of the previous
instructions), but by internally examining the status register. As was
just mentioned, there is a zero result flag in the status register. The
BEQ instruction branches if the zero result flag (known as Z) is set.
Every branch instruction has an opposite branch instruction. The BEQ
instruction has an opposite instruction BNE, which means Branch on result
Not Equal to zero (i.e., Z not set).
The index registers have a number of associated instructions which
modify their contents. For example, the INX instruction INcrements the X
index register. If the X register contained $FF before it was incremented
(the maximum number the X register can contain), it will "wrap around"
back to zero. If you wanted a program to continue to do something until
you had performed the increment of the X index that pushed it around to
zero, you could use the BNE instruction to continue "looping" around,
until X became zero.
The reverse of INX, is DEX, which is DEcrement the X index register. If
the X index register is zero, DEX wraps around to $FF. Similarly, there
are INY and DEY for the Y index register.
226 BASIC TO MACHINE LANGUAGE
~
But what if a program didn't want to wait until X or Y had reached (or
not reached) zero? Well there are comparison instructions, CPX and CPY,
which allow the machine language programmer to test the index registers
with specific values, or even the contents of memory locations. If you
wanted to see if the X register contained $40, you would use the
instruction:
The compare, and branch instructions play a major part in any machine
language program.
The operand specified in a branch instruction when using 64MON is the
address of the part of the program that the branch goes to when the
proper conditions are met. However, the operand is only an offset, which
gets you from where the program currently is to the address specified.
This offset is just one byte, and therefore the range that a branch
instruction can branch to is limited. It can branch from 128 bytes back-
ward, to 127 bytes forward.
+-----------------------------------------------------------------------+
| NOTE: This is a total range of 255 bytes which is, of course, the |
| maximum range of values one byte can contain. |
+-----------------------------------------------------------------------+
64MON will tell you if you "branch out of range" by refusing to "as-
semble" that particular instruction. But don't worry about that now be-
cause it's unlikely that you will have such branches for quite a while.
The branch is a "quick" instruction by machine language standards because
of the "offset" principle as opposed to an absolute address. 64MON allows
you to type in an absolute address, and it calculates the correct offset.
This is just one of the "comforts" of using an assembler.
+-----------------------------------------------------------------------+
| NOTE: It is NOT possible to cover every single branch instruction. For|
| further information, refer to the Bibliography section in Appendix F. |
+-----------------------------------------------------------------------+
SUBROUTINES
In machine language (in the same way as using BASIC), you can call
subroutines. The instruction to call a subroutine is JSR (Jump to Sub-
Routine), followed by the specified absolute address.
Incorporated in the operating system, there is a machine language
subroutine that will PRINT a character to the screen. The CBM ASCII code
of the character should be in the accumulator before calling the
subroutine. The address of this subroutine is $FFD2.
Therefore, to print "Hi" to the screen, the following program should be
entered:
The "PRINT a character" routine we have just used is part of the KERNAL
jump table. The instruction similar to GOTO in BASIC is JMP, which means
JUMP to the specified absolute address. The KERNAL is a long list of
"standardized" subroutines that control ALL input and output of the
Commodore 64. Each entry in the KERNAL JMPs to a subroutine in the
operating system. This "jump table" is found between memory locations
$FF84 to $FFF5 in the operating system. A full explanation of the KERNAL
is available in the "KERNAL Reference Section" of this manual. However,
certain routines are used here to show how easy and effective the KERNAL
is.
Let's now use the new principles you've just learned in another pro-
gram. It will help you to put the instructions into context:
This program. will display the alphabet using a KERNAL routine. The
only new instruction introduced here is TXA Transfer the contents of the
X index register, into the Accumulator.
To see the Commodore 64 print the alphabet, type the familiar command:
.G 1400
The comments that are beside the program, explain the program flow and
logic. If you are writing a program, write it on paper first, and then
test it in small parts if possible.
You should also use the utilities that are available, either IN your
computer, or in a program, that aid you in writing, editing, or tracking
down errors in a machine language program. An example would be the
KERNAL, which allows you to check the keyboard, print text, control
peripheral devices like disk drives, printers, modems, etc., manage
memory and the screen. It is extremely powerful and it is advised
strongly that it is used (refer to KERNAL section, Page 268).
Advantages of writing programs in machine language:
READY.
o Display title
o Ask if player requires instructions
o YES - display them-Go to START
o NO - Go to START
o START Initialize everything
o MAIN display roulette table
o Take in bets
o Spin wheel
o Slow wheel to stop
o Check bets with result
o Inform player
o Player any money left?
o YES - Go to MAIN
o NO - Inform user!, and go to START
This is the main outline. As each module is approached, you can break
it down further. If you look at a large indigestable problem as something
that can be broken down into small enough pieces to be eaten, then you'll
be able to approach something that seems impossible, and have it all fall
into place.
This process only improves with practice, so KEEP TRYING.
BASIC TO MACHINE LANGUAGE 231
~
+------------------------------------------------------------------------
|
| MCS6510 MICROPROCESSOR INSTRUCTION SET - ALPHABETIC SEQUENCE
|
+------------------------------------------------------------------------
|
| ADC Add Memory to Accumulator with Carry
| AND "AND" Memory with Accumulator
| ASL Shift Left One Bit (Memory or Accumulator)
|
| BCC Branch on Carry Clear
| BCS Branch on Carry Set
| BEQ Branch on Result Zero
| BIT Test Bits in Memory with Accumulator
| BMI Branch on Result Minus
| BNE Branch on Result not Zero
| BPL Branch on Result Plus
| BRK Force Break
| BVC Branch on Overflow Clear
| BVS Branch on Overflow Set
|
| CLC Clear Carry Flag
| CLD Clear Decimal Mode
| CLI Clear interrupt Disable Bit
| CLV Clear Overflow Flag
| CMP Compare Memory and Accumulator
| CPX Compare Memory and Index X
| CPY Compare Memory and Index Y
|
| DEC Decrement Memory by One
| DEX Decrement Index X by One
| DEY Decrement Index Y by One
|
| EOR "Exclusive-Or" Memory with Accumulator
|
| INC Increment Memory by One
| INX Increment Index X by One
| INY Increment Index Y by One
|
| JMP Jump to New Location
|
+------------------------------------------------------------------------
/ Change V Logical OR
Operation: A + M + C -> A, C N Z C I D V
/ / / _ _ /
(Ref: 2.2.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Immediate | ADC #Oper | 69 | 2 | 2 |
| Zero Page | ADC Oper | 65 | 2 | 3 |
| Zero Page,X | ADC Oper,X | 75 | 2 | 4 |
| Absolute | ADC Oper | 60 | 3 | 4 |
| Absolute,X | ADC Oper,X | 70 | 3 | 4* |
| Absolute,Y | ADC Oper,Y | 79 | 3 | 4* |
| (Indirect,X) | ADC (Oper,X) | 61 | 2 | 6 |
| (Indirect),Y | ADC (Oper),Y | 71 | 2 | 5* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if page boundary is crossed.
Operation: Branch on C = 1 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.4)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BCS Oper | B0 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to next page.
Operation: Branch on N = 1 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BMI Oper | 30 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 1 if branch occurs to different page.
Operation: Branch on Z = 0 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.6)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BMI Oper | D0 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to different page.
Operation: Branch on N = 0 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BPL Oper | 10 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to different page.
Operation: Branch on V = 0 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.8)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BVC Oper | 50 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to different page.
Operation: Branch on V = 1 N Z C I D V
_ _ _ _ _ _
(Ref: 4.1.1.7)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Relative | BVS Oper | 70 | 2 | 2* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if branch occurs to same page.
* Add 2 if branch occurs to different page.
Operation: 0 -> C N Z C I D V
_ _ 0 _ _ _
(Ref: 3.0.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | CLC | 18 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: 0 -> D N A C I D V
_ _ _ _ 0 _
(Ref: 3.3.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | CLD | D8 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: 0 -> I N Z C I D V
_ _ _ 0 _ _
(Ref: 3.2.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | CLI | 58 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: 0 -> V N Z C I D V
_ _ _ _ _ 0
(Ref: 3.6.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | CLV | B8 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: A - M N Z C I D V
/ / / _ _ _
(Ref: 4.2.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Immediate | CMP #Oper | C9 | 2 | 2 |
| Zero Page | CMP Oper | C5 | 2 | 3 |
| Zero Page,X | CMP Oper,X | D5 | 2 | 4 |
| Absolute | CMP Oper | CD | 3 | 4 |
| Absolute,X | CMP Oper,X | DD | 3 | 4* |
| Absolute,Y | CMP Oper,Y | D9 | 3 | 4* |
| (Indirect,X) | CMP (Oper,X) | C1 | 2 | 6 |
| (Indirect),Y | CMP (Oper),Y | D1 | 2 | 5* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if page boundary is crossed.
Operation: M - 1 -> M N Z C I D V
/ / _ _ _ _
(Ref: 10.7)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Zero Page | DEC Oper | C6 | 2 | 5 |
| Zero Page,X | DEC Oper,X | D6 | 2 | 6 |
| Absolute | DEC Oper | CE | 3 | 6 |
| Absolute,X | DEC Oper,X | DE | 3 | 7 |
+----------------+-----------------------+---------+---------+----------+
Operation: X - 1 -> X N Z C I D V
/ / _ _ _ _
(Ref: 7.6)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | DEX | CA | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: X - 1 -> Y N Z C I D V
/ / _ _ _ _
(Ref: 7.7)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | DEY | 88 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
242 BASIC TO MACHINE LANGUAGE
~
Operation: X + 1 -> X N Z C I D V
/ / _ _ _ _
(Ref: 7.5)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | INY | C8 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: M -> A N Z C I D V
/ / _ _ _ _
(Ref: 2.1.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Immediate | LDA #Oper | A9 | 2 | 2 |
| Zero Page | LDA Oper | A5 | 2 | 3 |
| Zero Page,X | LDA Oper,X | B5 | 2 | 4 |
| Absolute | LDA Oper | AD | 3 | 4 |
| Absolute,X | LDA Oper,X | BD | 3 | 4* |
| Absolute,Y | LDA Oper,Y | B9 | 3 | 4* |
| (Indirect,X) | LDA (Oper,X) | A1 | 2 | 6 |
| (Indirect),Y | LDA (Oper),Y | B1 | 2 | 5* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 if page boundary is crossed.
Operation: M -> X N Z C I D V
/ / _ _ _ _
(Ref: 7.0)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Immediate | LDX #Oper | A2 | 2 | 2 |
| Zero Page | LDX Oper | A6 | 2 | 3 |
| Zero Page,Y | LDX Oper,Y | B6 | 2 | 4 |
| Absolute | LDX Oper | AE | 3 | 4 |
| Absolute,Y | LDX Oper,Y | BE | 3 | 4* |
+----------------+-----------------------+---------+---------+----------+
* Add 1 when page boundary is crossed.
+-+-+-+-+-+-+-+-+
Operation: 0 -> |7|6|5|4|3|2|1|0| -> C N Z C I D V
+-+-+-+-+-+-+-+-+ 0 / / _ _ _
(Ref: 10.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Accumulator | LSR A | 4A | 1 | 2 |
| Zero Page | LSR Oper | 46 | 2 | 5 |
| Zero Page,X | LSR Oper,X | 56 | 2 | 6 |
| Absolute | LSR Oper | 4E | 3 | 6 |
| Absolute,X | LSR Oper,X | 5E | 3 | 7 |
+----------------+-----------------------+---------+---------+----------+
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | NOP | EA | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: A V M -> A N Z C I D V
/ / _ _ _ _
(Ref: 2.2.3.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Immediate | ORA #Oper | 09 | 2 | 2 |
| Zero Page | ORA Oper | 05 | 2 | 3 |
| Zero Page,X | ORA Oper,X | 15 | 2 | 4 |
| Absolute | ORA Oper | 0D | 3 | 4 |
| Absolute,X | ORA Oper,X | 10 | 3 | 4* |
| Absolute,Y | ORA Oper,Y | 19 | 3 | 4* |
| (Indirect,X) | ORA (Oper,X) | 01 | 2 | 6 |
| (Indirect),Y | ORA (Oper),Y | 11 | 2 | 5 |
+----------------+-----------------------+---------+---------+----------+
* Add 1 on page crossing
Operation: A toS N Z C I D V
_ _ _ _ _ _
(Ref: 8.5)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | PHA | 48 | 1 | 3 |
+----------------+-----------------------+---------+---------+----------+
Operation: P toS N Z C I D V
_ _ _ _ _ _
(Ref: 8.11)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | PHP | 08 | 1 | 3 |
+----------------+-----------------------+---------+---------+----------+
Operation: A fromS N Z C I D V
_ _ _ _ _ _
(Ref: 8.6)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | PLA | 68 | 1 | 4 |
+----------------+-----------------------+---------+---------+----------+
Operation: P fromS N Z C I D V
From Stack
(Ref: 8.12)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | PLP | 28 | 1 | 4 |
+----------------+-----------------------+---------+---------+----------+
+------------------------------+
| M or A |
| +-+-+-+-+-+-+-+-+ +-+ |
Operation: +-< |7|6|5|4|3|2|1|0| <- |C| <-+ N Z C I D V
+-+-+-+-+-+-+-+-+ +-+ / / / _ _ _
(Ref: 10.3)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Accumulator | ROL A | 2A | 1 | 2 |
| Zero Page | ROL Oper | 26 | 2 | 5 |
| Zero Page,X | ROL Oper,X | 36 | 2 | 6 |
| Absolute | ROL Oper | 2E | 3 | 6 |
| Absolute,X | ROL Oper,X | 3E | 3 | 7 |
+----------------+-----------------------+---------+---------+----------+
Operation: 1 -> C N Z C I D V
_ _ 1 _ _ _
(Ref: 3.0.1)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | SEC | 38 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: A -> M N Z C I D V
_ _ _ _ _ _
(Ref: 2.1.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Zero Page | STA Oper | 85 | 2 | 3 |
| Zero Page,X | STA Oper,X | 95 | 2 | 4 |
| Absolute | STA Oper | 80 | 3 | 4 |
| Absolute,X | STA Oper,X | 90 | 3 | 5 |
| Absolute,Y | STA Oper, Y | 99 | 3 | 5 |
| (Indirect,X) | STA (Oper,X) | 81 | 2 | 6 |
| (Indirect),Y | STA (Oper),Y | 91 | 2 | 6 |
+----------------+-----------------------+---------+---------+----------+
Operation: X -> M N Z C I D V
_ _ _ _ _ _
(Ref: 7.2)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Zero Page | STX Oper | 86 | 2 | 3 |
| Zero Page,Y | STX Oper,Y | 96 | 2 | 4 |
| Absolute | STX Oper | 8E | 3 | 4 |
+----------------+-----------------------+---------+---------+----------+
Operation: Y -> M N Z C I D V
_ _ _ _ _ _
(Ref: 7.3)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Zero Page | STY Oper | 84 | 2 | 3 |
| Zero Page,X | STY Oper,X | 94 | 2 | 4 |
| Absolute | STY Oper | 8C | 3 | 4 |
+----------------+-----------------------+---------+---------+----------+
Operation: A -> X N Z C I D V
/ / _ _ _ _
(Ref: 7.11)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | TAX | AA | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: A -> Y N Z C I D V
/ / _ _ _ _
(Ref: 7.13)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | TAY | A8 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: S -> X N Z C I D V
/ / _ _ _ _
(Ref: 8.9)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | TSX | BA | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
Operation: Y -> A N Z C I D V
/ / _ _ _ _
(Ref: 7.14)
+----------------+-----------------------+---------+---------+----------+
| Addressing Mode| Assembly Language Form| OP CODE |No. Bytes|No. Cycles|
+----------------+-----------------------+---------+---------+----------+
| Implied | TYA | 98 | 1 | 2 |
+----------------+-----------------------+---------+---------+----------+
A A A B B B B B B B B B B C
D N S C C E I M N P R V V L
C D L C S Q T I E L K C S C
Accumulator | . . 2 . . . . . . . . . . .
Immediate | 2 2 . . . . . . . . . . .
Zero Page | 3 3 5 . . . 3 . . . . . . .
Zero Page,X | 4 4 6 . . . . . . . . . . .
Zero Page,Y | . . . . . . . . . . . . . .
Absolute | 4 4 6 . . . 4 . . . . . . .
Absolute,X | 4* 4* 7 . . . . . . . . . . .
Absolute,Y | 4* 4* . . . . . . . . . . . .
Implied | . . . . . . . . . . . . . 2
Relative | . . . 2** 2** 2** . 2** 2** 2** 7 2** 2** .
(Indirect,X) | 6 6 . . . . . . . . . . . .
(Indirect),Y | 5* 5* . . . . . . . . . . . .
Abs. Indirect| . . . . . . . . . . . . . .
+-----------------------------------------------------------
C C C C C C D D D E I I I J
L L L M P P E E E O N N N M
D I V P X Y C X Y R C X Y P
Accumulator | . . . . . . . . . . . . . .
Immediate | . . . 2 2 2 . . . 2 . . . .
Zero Page | . . . 3 3 3 5 . . 3 5 . . .
Zero Page,X | . . . 4 . . 6 . . 4 6 . . .
Zero Page,Y | . . . . . . . . . . . . . .
Absolute | . . . 4 4 4 6 . . 4 6 . . 3
Absolute,X | . . . 4* . . 7 . . 4* 7 . . .
Absolute,Y | . . . 4* . . . . . 4* . . . .
Implied | 2 2 2 . . . . 2 2 . . 2 2 .
Relative | . . . . . . . . . . . . . .
(Indirect,X) | . . . 6 . . . . . 6 . . . .
(Indirect),Y | . . . 5* . . . . . 5* . . . .
Abs. Indirect| . . . . . . . . . . . . . 5
+-----------------------------------------------------------
* Add one cycle if indexing across page boundary
** Add one cycle if branch is taken, Add one additional if branching
operation crosses page boundary
------------------------------------------------------------------------+
INSTRUCTION ADDRESSING MODES AND RELATED EXECUTION TIMES |
(in clock cycles) |
------------------------------------------------------------------------+
J L L L L N O P P P P R R R
S D D D S O R H H L L O O T
R A X Y R P A A P A P L R I
Accumulator | . . . . 2 . . . . . . 2 2 .
Immediate | . 2 2 2 . . 2 . . . . . . .
Zero Page | . 3 3 3 5 . 3 . . . . 5 5 .
Zero Page,X | . 4 . 4 6 . 4 . . . . 6 6 .
Zero Page,Y | . . 4 . . . . . . . . . . .
Absolute | 6 4 4 4 6 . 4 . . . . 6 6 .
Absolute,X | . 4* . 4* 7 . 4* . . . . 7 7 .
Absolute,Y | . 4* 4* . . . 4* . . . . . . .
Implied | . . . . . 2 . 3 3 4 4 . . 6
Relative | . . . . . . . . . . . . . .
(Indirect,X) | . 6 . . . . 6 . . . . . . .
(Indirect),Y | . 5* . . . . 5* . . . . . . .
Abs. Indirect| . . . . . . . . . . . . . .
+-----------------------------------------------------------
R S S S S S S S T T T T T T
T B E E E T T T A A S X X Y
S C C D I A X Y X Y X A S A
Accumulator | . . . . . . . . . . . . . .
Immediate | . 2 . . . . . . . . . . . .
Zero Page | . 3 . . . 3 3 3 . . . . . .
Zero Page,X | . 4 . . . 4 . 4 . . . . . .
Zero Page,Y | . . . . . . 4 . . . . . . .
Absolute | . 4 . . . 4 4 4 . . . . . .
Absolute,X | . 4* . . . 5 . . . . . . . .
Absolute,Y | . 4* . . . 5 . . . . . . . .
Implied | 6 . 2 2 2 . . . 2 2 2 2 2 2
Relative | . . . . . . . . . . . . . .
(Indirect,X) | . 6 . . . 6 . . . . . . . .
(Indirect),Y | . 5* . . . 6 . . . . . . . .
Abs. Indirect| . . . . . . . . . . . . . .
+-----------------------------------------------------------
* Add one cycle if indexing across page boundary
** Add one cycle if branch is taken, Add one additional if branching
operation crosses page boundary
00 - BRK 20 - JSR
01 - ORA - (Indirect,X) 21 - AND - (Indirect,X)
02 - Future Expansion 22 - Future Expansion
03 - Future Expansion 23 - Future Expansion
04 - Future Expansion 24 - BIT - Zero Page
05 - ORA - Zero Page 25 - AND - Zero Page
06 - ASL - Zero Page 26 - ROL - Zero Page
07 - Future Expansion 27 - Future Expansion
08 - PHP 28 - PLP
09 - ORA - Immediate 29 - AND - Immediate
0A - ASL - Accumulator 2A - ROL - Accumulator
0B - Future Expansion 2B - Future Expansion
0C - Future Expansion 2C - BIT - Absolute
0D - ORA - Absolute 2D - AND - Absolute
0E - ASL - Absolute 2E - ROL - Absolute
0F - Future Expansion 2F - Future Expansion
10 - BPL 30 - BMI
11 - ORA - (Indirect),Y 31 - AND - (Indirect),Y
12 - Future Expansion 32 - Future Expansion
13 - Future Expansion 33 - Future Expansion
14 - Future Expansion 34 - Future Expansion
15 - ORA - Zero Page,X 35 - AND - Zero Page,X
16 - ASL - Zero Page,X 36 - ROL - Zero Page,X
17 - Future Expansion 37 - Future Expansion
18 - CLC 38 - SEC
19 - ORA - Absolute,Y 39 - AND - Absolute,Y
1A - Future Expansion 3A - Future Expansion
1B - Future Expansion 3B - Future Expansion
1C - Future Expansion 3C - Future Expansion
1D - ORA - Absolute,X 3D - AND - Absolute,X
1E - ASL - Absolute,X 3E - ROL - Absolute,X
1F - Future Expansion 3F - Future Expansion
40 - RTI 60 - RTS
41 - EOR - (Indirect,X) 61 - ADC - (Indirect,X)
42 - Future Expansion 62 - Future Expansion
43 - Future Expansion 63 - Future Expansion
44 - Future Expansion 64 - Future Expansion
45 - EOR - Zero Page 65 - ADC - Zero Page
46 - LSR - Zero Page 66 - ROR - Zero Page
47 - Future Expansion 67 - Future Expansion
48 - PHA 68 - PLA
49 - EOR - Immediate 69 - ADC - Immediate
4A - LSR - Accumulator 6A - ROR - Accumulator
4B - Future Expansion 6B - Future Expansion
4C - JMP - Absolute 6C - JMP - Indirect
4D - EOR - Absolute 6D - ADC - Absolute
4E - LSR - Absolute 6E - ROR - Absolute
4F - Future Expansion 6F - Future Expansion
50 - BVC 70 - BVS
51 - EOR - (Indirect),Y 71 - ADC - (Indirect),Y
52 - Future Expansion 72 - Future Expansion
53 - Future Expansion 73 - Future Expansion
54 - Future Expansion 74 - Future Expansion
55 - EOR - Zero Page,X 75 - ADC - Zero Page,X
56 - LSR - Zero Page,X 76 - ROR - Zero Page,X
57 - Future Expansion 77 - Future Expansion
58 - CLI 78 - SEI
59 - EOR - Absolute,Y 79 - ADC - Absolute,Y
5A - Future Expansion 7A - Future Expansion
5B - Future Expansion 7B - Future Expansion
5C - Future Expansion 7C - Future Expansion
50 - EOR - Absolute,X 70 - ADC - Absolute,X
5E - LSR - Absolute,X 7E - ROR - Absolute,X
5F - Future Expansion 7F - Future Expansion
The Commodore 64 has 64K bytes of RAM. It also has 20K bytes of ROM,
containing BASIC, the operating system, and the standard character set.
It also accesses input/output devices as a 4K chunk of memory. How is
this all possible on a computer with a 16-bit address bus, that is
normally only capable of addressing 64K?
The secret is in the 6510 processor chip itself. On the chip is an
input/output port. This port is used to control whether RAM or ROM or I/O
will appear in certain portions of the system's memory. The port is also
used to control the Datassette(TM), so it is important to affect only the
proper bits.
The 6510 input/output port appears at location 1. The data direction
register for this port appears at location 0. The port is controlled like
any of the other input/output ports in the system... the data direction
controls whether a given bit will be an input or an output, and the
actual data transfer occurs through the port itself. The lines in the
6510 control port are defined as follows:
+---------+---+------------+--------------------------------------------+
| NAME |BIT| DIRECTION | DESCRIPTION |
+---------+---+------------+--------------------------------------------+
| LORAM | 0 | OUTPUT | Control for RAM/ROM at $A000-$BFFF |
| HIRAM | 1 | OUTPUT | Control for RAM/ROM at $E000-$FFFF |
| CHAREN | 2 | OUTPUT | Control for I/O/ROM at $D000-$DFFF |
| | 3 | OUTPUT | Cassette write line |
| | 4 | INPUT | Cassette switch sense (0=play button down) |
| | 5 | OUTPUT | Cassette motor control (0=motor spins) |
+---------+---+------------+--------------------------------------------+
BITS 5 4 3 2 1 0
----------------
1 0 1 1 1 1
+-----------------------------------------------------------------------+
| NOTE: In any memory map containing ROM, a WRITE (a POKE) to a ROM |
| location will store data in the RAM "under" the ROM. Writing to a ROM |
| location stores data in the "hidden" RAM. For example, this allows a |
| hi-resolution screen to be kept underneath a ROM, and be changed |
| without having to bank the screen back into the processor address |
| space. Of course a READ of a ROM location will return the contents of |
| the ROM, not the "hidden" RAM. |
+-----------------------------------------------------------------------+
+----------------------------+
| 8K KERNAL ROM |
E000-FFFF | OR RAM |
+----------------------------+
D000-DFFF | 4K I/O OR RAM OR CHAR. ROM |
+----------------------------+
C000-CFFF | 4K RAM |
+----------------------------+
| 8K BASIC ROM OR RAM |
A000-BFFF | OR ROM PLUG-IN |
+----------------------------+
| 8K RAM |
8000-9FFF | OR ROM PLUG-IN |
+----------------------------+
| |
| |
| 16 K RAM |
4000-7FFF | |
+----------------------------+
| |
| |
| 16 K RAM |
0000-3FFF | |
+----------------------------+
I/O BREAKDOWN
The two open I/O slots are for general purpose user I/O, special pur-
pose I/O cartridges (such as IEEE), and have been tentatively designated
for enabling the Z-80 cartridge (CP/M option) and for interfacing to a
low-cost high-speed disk system.
The system provides for "auto-start" of the program in a Commodore 64
Expansion Cartridge. The cartridge program is started if the first nine
bytes of the cartridge ROM starting at location 32768 ($8000) contain
specific data. The first two bytes must hold the Cold Start vector to be
used by the cartridge program. The next two bytes at 32770 ($8002) must
be the Warm Start vector used by the cartridge program. The next three
bytes must be the letters, CBM, with bit 7 set in each letter. The last
two bytes must be the digits "80" in PET ASCII.
6000
RAM RAM RAM RAM RAM RAM RAM RAM -
5000
4000
-------------------------------------------------------------------------
3000
1000
-------------------------------------------------------------------------
0000 RAM RAM RAM RAM RAM RAM RAM RAM RAM
-------------------------------------------------------------------------
NOTE: (1) (2) (3) (4) (5) (6) (7) (8) (9)
(2) This map provides 60K bytes of RAM and I/O devices.
The user must write his own I/O driver routines.
(9) This is the ULTIMAX video game memory map. Note that
the 2K byte "expansion RAM" for the ULTIMAX, if
required, is accessed out of the COMMODORE 64 and
any RAM in the cartridge is ignored.
THE KERNAL
A good question at this point is why use the jump table at all? Why not
just JSR directly to the KERNAL subroutine involved? The jump table is
used so that if the KERNAL or BASIC is changed, your machine language
programs will still work. In future operating systems the routines may
have their memory locations moved around to a different position in the
memory map... but the jump table will still work correctly!
1) On power-up, the KERNAL first resets the stack pointer, and clears
decimal mode.
2) The KERNAL then checks for the presence of an autostart ROM cartridge
at location $8000 HEX (32768 decimal). If this is present, normal
initialization is suspended, and control is transferred to the car-
tridge code. If an autostart ROM is not present, normal system ini-
tialization continues.
3) Next, the KERNAL initializes all INPUT/OUTPUT devices. The serial bus
is initialized. Both 6526 CIA chips are set to the proper values for
keyboard scanning, and the 60-Hz timer is activated. The SID chip is
cleared. The BASIC memory map is selected and the cassette motor is
switched off.
4) Next, the KERNAL performs a RAM test, setting the top and bottom of
memory pointers. Also, page zero is initialized, and the tape buffer
is set up.
The RAM TEST routine is a nondestructive test starting at location
$0300 and working upward. Once the test has found the first non-RAM
location, the top of RAM has its pointer set. The bottom of memory is
always set to $0800, and the screen setup is always set at $0400.
5) Finally, the KERNAL performs these other activities. I/O vectors are
set to default values. The indirect jump table in low memory is estab-
lished. The screen is then cleared, and all screen editor variables
reset. Then the indirect at $A000 is used to start BASIC.
1) Set up
2) Call the routine
3) Error handling
- CALL ADDRESS: This is the call address of the KERNAL routine, given in
hexadecimal.
- ERROR RETURNS: A return from a KERNAL routine with the CARRY set
indicates that an error was encountered in processing. The accumulator
will contain the number of the error.
- REGISTERS AFFECTED: All registers used by the KERNAL routine are listed
here.
+--------+-------------------+------------------------------------------+
| | ADDRESS | |
| NAME +---------+---------+ FUNCTION |
| | HEX | DECIMAL | |
+--------+---------+---------+------------------------------------------+
| PLOT | $FFF0 | 65520 | Read/set X,Y cursor position |
| RAMTAS | $FF87 | 65415 | Initialize RAM, allocate tape buffer, |
| | | | set screen $0400 |
| RDTIM | $FFDE | 65502 | Read real time clock |
| READST | $FFB7 | 65463 | Read I/O status word |
| RESTOR | $FF8A | 65418 | Restore default I/O vectors |
| SAVE | $FFD8 | 65496 | Save RAM to device |
| SCNKEY | $FF9F | 65439 | Scan keyboard |
| SCREEN | $FFED | 65517 | Return X,Y organization of screen |
| SECOND | $FF93 | 65427 | Send secondary address after LISTEN |
| SETLFS | $FFBA | 65466 | Set logical, first, and second addresses|
| SETMSG | $FF90 | 65424 | Control KERNAL messages |
| SETNAM | $FFBD | 65469 | Set file name |
| SETTIM | $FFDB | 65499 | Set real time clock |
| SETTMO | $FFA2 | 65442 | Set timeout on serial bus |
| STOP | $FFE1 | 65505 | Scan stop key |
| TALK | $FFB4 | 65460 | Command serial bus device to TALK |
| TKSA | $FF96 | 65430 | Send secondary address after TALK |
| UDTIM | $FFEA | 65514 | Increment real time clock |
| UNLSN | $FFAE | 65454 | Command serial bus to UNLISTEN |
| UNTLK | $FFAB | 65451 | Command serial bus to UNTALK |
| VECTOR | $FF8D | 65421 | Read/set vectored I/O |
+--------+---------+---------+------------------------------------------+
BASIC TO MACHINE LANGUAGE 273
~
Description: This is the routine to use when you want to get informa-
tion from a device on the serial bus, like a disk. This routine gets a
byte of data off the serial bus using full handshaking. The data is
returned in the accumulator. To prepare for this routine the TALK routine
must be called first to command the device on the serial bus to send data
through the bus. If the input device needs a secondary command, it must
be sent by using the TKSA KERNAL routine before calling this routine.
Errors are returned in the status word. The READST routine is used to
read the status word.
How to Use:
EXAMPLE:
Description: Any logical file that has already been opened by the
KERNAL OPEN routine can be defined as an input channel by this routine.
Naturally, the device on the channel must be an input device. Otherwise
an error will occur, and the routine will abort.
If you are getting data from anywhere other than the keyboard, this
routine must be called before using either the CHRIN or the GETIN KERNAL
routines for data input. If you want to use the input from the keyboard,
and no other input channels are opened, then the calls to this routine,
and to the OPEN routine are not needed.
When this routine is used with a device on the serial bus, it auto-
matically sends the talk address (and the secondary address if one was
specified by the OPEN routine) over the bus.
How to Use:
EXAMPLE:
How to Use:
+-----------------------------------------------------------------------+
| REMEMBER: this routine is NOT NEEDED to send data to the screen. |
+-----------------------------------------------------------------------+
0) Use the KERNAL OPEN routine to specify a logical file number, a
LISTEN address, and a secondary address (if needed).
1) Load the X register with the logical file number used in the open
statement.
2) Call this routine (by using the JSR instruction).
EXAMPLE:
How to Use:
EXAMPLE:
EXAMPLE:
JSR CHRIN
STA DATA
EXAMPLE:
JSR CHRIN
STA DATA
+-----------------------------------------------------------------------+
| NOTE: Care must be taken when using this routine to send data to a |
| specific serial device since data will be sent to all open output |
| channels on the bus. Unless this is desired, all open output channels |
| on the serial bus other than the intended destination channel must be |
| closed by a call to the KERNAL CLRCHN routine. |
+-----------------------------------------------------------------------+
How to Use:
EXAMPLE:
How to Use:
0) Use the LISTEN KERNAL routine (and the SECOND routine if needed).
1) Load the accumulator with a byte of data.
2) Call this routine to send the data byte.
EXAMPLE:
Description: This routine sets up the 6567 video controller chip in the
Commodore 64 for normal operation. The KERNAL screen editor is also
initialized. This routine should be called by a Commodore 64 program
cartridge.
How to Use:
EXAMPLE:
JSR CINT
JMP RUN ;BEGIN EXECUTION
Description: This routine closes all open files. When this routine is
called, the pointers into the open file table are reset, closing all
files. Also, the CLRCHN routine is automatically called to reset the I/O
channels.
How to Use:
EXAMPLE:
JSR CLALL ;CLOSE ALL FILES AND SELECT DEFAULT I/O CHANNELS
JMP RUN ;BEGIN EXECUTION
Description: This routine is used to close a logical file after all I/O
operations have been completed on that file. This routine is called after
the accumulator is loaded with the logical file number to be closed (the
same number used when the file was opened using the OPEN routine).
How to Use:
EXAMPLE:
;CLOSE 15
LDA #15
JSR CLOSE
Description: This routine is called to clear all open channels and re-
store the I/O channels to their original default values. It is usually
called after opening other I/O channels (like a tape or disk drive) and
using them for input/output operations. The default input device is 0
(keyboard). The default output device is 3 (the Commodore 64 screen).
If one of the channels to be closed is to the serial port, an UNTALK
signal is sent first to clear the input channel or an UNLISTEN is sent to
clear the output channel. By not calling this routine (and leaving lis-
tener(s) active on the serial bus) several devices can receive the same
data from the Commodore 64 at the same time. One way to take advantage
of this would be to command the printer to TALK and the disk to LISTEN.
This would allow direct printing of a disk file.
This routine is automatically called when the KERNAL CLALL routine is
executed.
How to Use:
1) Call this routine using the JSR instruction.
EXAMPLE:
JSR CLRCHN
How to Use:
EXAMPLE:
How to Use:
EXAMPLE:
EXAMPLE:
JSR IOINIT
How to Use:
1) Load the accumulator with the number of the device to command
to LISTEN.
2) Call this routine using the JSR instruction.
EXAMPLE:
;COMMAND DEVICE #8 TO LISTEN
LDA #8
JSR LISTEN
BASIC TO MACHINE LANGUAGE 285
~
Description: This routine LOADs data bytes from any input device di-
rectly into the memory of the Commodore 64. It can also be used for a
verify operation, comparing data from a device with the data already in
memory, while leaving the data stored in RAM unchanged.
The accumulator (.A) must be set to 0 for a LOAD operation, or 1 for a
verify, If the input device is OPENed with a secondary address (SA) of 0
the header information from the device is ignored. In this case, the X
and Y registers must contain the starting address for the load. If the
device is addressed with a secondary address of 1, then the data is
loaded into memory starting at the location specified by the header. This
routine returns the address of the highest RAM location loaded.
Before this routine can be called, the KERNAL SETLFS, and SETNAM
routines must be called.
+-----------------------------------------------------------------------+
| NOTE: You can NOT LOAD from the keyboard (0), RS-232 (2), or the |
| screen (3). |
+-----------------------------------------------------------------------+
How to Use:
EXAMPLE:
How to Use:
TO READ THE BOTTOM OF RAM
1) Set the carry.
2) Call this routine.
EXAMPLE:
Description: This routine is used to set the top of RAM. When this
routine is called with the carry bit of the accumulator set, the pointer
to the top of RAM will be loaded into the X and Y registers. When this
routine is called with the accumulator carry bit clear, the contents of
the X and Y registers are loaded in the top of memory pointer, changing
the top of memory.
EXAMPLE:
;DEALLOCATE THE RS-232 BUFFER
SEC
JSR MEMTOP ;READ TOP OF MEMORY
DEX
CLC
JSR MEMTOP ;SET NEW TOP OF MEMORY
How to Use:
EXAMPLE:
How to Use:
EXAMPLE:
Description: This routine is used to test RAM and set the top and
bottom of memory pointers accordingly. It also clears locations $0000 to
$0101 and $0200 to $03FF. It also allocates the cassette buffer, and sets
the screen base to $0400. Normally, this routine is called as part of the
initialization process of a Commodore 64 program cartridge.
EXAMPLE:
JSR RAMTAS
Description: This routine is used to read the system clock. The clock's
resolution is a 60th of a second. Three bytes are returned by the
routine. The accumulator contains the most significant byte, the X index
register contains the next most significant byte, and the Y index
register contains the least significant byte.
EXAMPLE:
JSR RDTIM
STY TIME
STX TIME+1
STA TIME+2
...
TIME *=*+3
BASIC TO MACHINE LANGUAGE 291
~
Description: This routine returns the current status of the I/O devices
in the accumulator. The routine is usually called after new communication
to an I/O device. The routine gives you information about device status,
or errors that have occurred during the I/O operation.
The bits returned in the accumulator contain the following information:
(see table below)
+---------+------------+---------------+------------+-------------------+
| ST Bit | ST Numeric | Cassette | Serial | Tape Verify |
| Position| Value | Read | Bus R/W | + Load |
+---------+------------+---------------+------------+-------------------+
| 0 | 1 | | time out | |
| | | | write | |
+---------+------------+---------------+------------+-------------------+
| 1 | 2 | | time out | |
| | | | read | |
+---------+------------+---------------+------------+-------------------+
| 2 | 4 | short block | | short block |
+---------+------------+---------------+------------+-------------------+
| 3 | 8 | long block | | long block |
+---------+------------+---------------+------------+-------------------+
| 4 | 16 | unrecoverable | | any mismatch |
| | | read error | | |
+---------+------------+---------------+------------+-------------------+
| 5 | 32 | checksum | | checksum |
| | | error | | error |
+---------+------------+---------------+------------+-------------------+
| 6 | 64 | end of file | EOI line | |
+---------+------------+---------------+------------+-------------------+
| 7 | -128 | end of tape | device not | end of tape |
| | | | present | |
+---------+------------+---------------+------------+-------------------+
How to Use:
EXAMPLE:
How to Use:
1) Call this routine.
EXAMPLE:
JSR RESTOR
+-----------------------------------------------------------------------+
| NOTE: Device 0 (the keyboard), device 2 (RS-232), and device 3 (the |
| screen) cannot be SAVEd to. If the attempt is made, an error occurs, |
| and the SAVE is stopped. |
+-----------------------------------------------------------------------+
How to Use:
0) Use the SETLFS routine and the SETNAM routine (unless a SAVE with no
file name is desired on "a save to the tape recorder"),
1) Load two consecutive locations on page 0 with a pointer to the start
of your save (in standard 6502 low byte first, high byte next
format).
2) Load the accumulator with the single byte page zero offset to the
pointer.
3) Load the X and Y registers with the low byte and high byte re-
spectively of the location of the end of the save.
4) Call this routine.
EXAMPLE:
How to Use:
EXAMPLE:
How to Use:
EXAMPLE:
JSR SCREEN
STX MAXCOL
STY MAXROW
How to Use:
EXAMPLE:
Description: This routine sets the logical file number, device address,
and secondary address (command number) for other KERNAL routines.
The logical file number is used by the system as a key to the file
table created by the OPEN file routine. Device addresses can range from 0
to 31. The following codes are used by the Commodore 64 to stand for the
CBM devices listed below:
ADDRESS DEVICE
0 Keyboard
1 Datassette(TM)
2 RS-232C device
3 CRT display
4 Serial bus printer
8 CBM serial bus disk drive
How to Use:
EXAMPLE:
How to Use:
EXAMPLE:
LDA #$40
JSR SETMSG ;TURN ON CONTROL MESSAGES
LDA #$80
JSR SETMSG ;TURN ON ERROR MESSAGES
LDA #0
JSR SETMSG ;TURN OFF ALL KERNAL MESSAGES
Description: This routine is used to set up the file name for the OPEN,
SAVE, or LOAD routines. The accumulator must be loaded with the length of
the file name. The X and Y registers must be loaded with the address of
the file name, in standard 6502 low-byte/high-byte format. The address
can be any valid memory address in the system where a string of
characters for the file name is stored. If no file name is desired, the
accumulator must be set to 0, representing a zero file length. The X and
Y registers can be set to any memory address in that case.
How to Use:
EXAMPLE:
How to Use:
1) Load the accumulator with the MSB of the 3-byte number to set the
clock.
2) Load the X register with the next byte.
3) Load the Y register with the LSB.
4) Call this routine.
EXAMPLE:
;SET THE CLOCK TO 10 MINUTES = 3600 JIFFIES
LDA #0 ;MOST SIGNIFICANT
LDX #>3600
LDY #<3600 ;LEAST SIGNIFICANT
JSR SETTIM
+-----------------------------------------------------------------------+
| NOTE: The Commodore 64 uses the timeout feature to communicate that a |
| disk file is not found on an attempt to OPEN a file only with an IEEE |
| card. |
+-----------------------------------------------------------------------+
How to Use:
EXAMPLE:
;DISABLE TIMEOUT
LDA #0
JSR SETTMO
How to Use:
0) UDTIM should be called before this routine.
1) Call this routine.
2) Test for the zero flag.
BASIC TO MACHINE LANGUAGE 301
~
EXAMPLE:
How to Use:
EXAMPLE:
How to Use:
EXAMPLE:
How to Use:
1) Call this routine.
EXAMPLE:
JSR UDTIM
BASIC TO MACHINE LANGUAGE 303
~
How to Use:
1) Call this routine.
EXAMPLE:
JSR UNLSN
How to Use:
1) Call this routine.
EXAMPLE:
JSR UNTALK
+-----------------------------------------------------------------------+
| NOTE: This routine requires caution in its use. The best way to use it|
| is to first read the entire vector contents into the user area, alter |
| the desired vectors, and then copy the contents back to the system |
| vectors. |
+-----------------------------------------------------------------------+
How to Use:
EXAMPLE:
;CHANGE THE INPUT ROUTINES TO NEW SYSTEM
LDX #<USER
LDY #>USER
SEC
JSR VECTOR ;READ OLD VECTORS
LDA #<MYINP ;CHANGE INPUT
STA USER+10
LDA #>MYINP
STA USER+11
LDX #<USER
LDY #>USER
CLC
JSR VECTOR ;ALTER SYSTEM
...
USER *=*+26
ERROR CODES
The following is a list of error messages which can occur when using
the KERNAL routines. If an error occurs during a KERNAL routine , the
carry bit of the accumulator is set, and the number of the error message
is returned in the accumulator.
+-----------------------------------------------------------------------+
| NOTE: Some KERNAL I/O routines do not use these codes for error |
| messages. Instead, errors are identified using the KERNAL READST |
| routine. |
+-----------------------------------------------------------------------+
+-------+---------------------------------------------------------------+
| NUMBER| MEANING |
+-------+---------------------------------------------------------------+
| 0 | Routine terminated by the <STOP> key |
| 1 | Too many open files |
| 2 | File already open |
| 3 | File not open |
| 4 | File not found |
| 5 | Device not present |
| 6 | File is not an input file |
| 7 | File is not an output file |
| 8 | File name is missing |
| 9 | Illegal device number |
| 240 | Top-of-memory change RS-232 buffer allocation/deallocation |
+-------+---------------------------------------------------------------+
306 BASIC TO MACHINE LANGUAGE
~
+-----------------------------------------------------------------------+
| NOTE: ALWAYS DISABLE INTERRUPTS BEFORE CHANGING THIS VECTOR! |
+-----------------------------------------------------------------------+
10 POKE51,L:POKE52,H:POKE55,1:POKE56,H:CLR
Where H and L are the high and low portions, respectively, of the new
top of memory. For example, to reserve the area from $9000 to $9FFF for
machine language, use the following:
10 POKE5110:POKE52,144:POKE5510:POKE56,144:CLR
1) DATA STATEMENTS:
By READing DATA statements, and POKEing the values into memory at the
start of the program, machine language routines can be added. This is the
easiest method. No special methods are needed to save the two parts of
the program, and it is fairly easy to debug. The drawbacks include taking
up more memory space, and the wait while the program is POKED in.
Therefore, this method is better for smaller routines.
EXAMPLE:
10 RESTORE:FORX=1T09:READA:POKE12*4096+X,A:NEXT
.
BASIC PROGRAM
.
1000 DATA 161,1,204,204,204,204,204,204,96
EXAMPLE:
10 IF FLAG=L THEN 20
15 FLAG=1:LOAD"MACHINE LANGUAGE ROUTINE NAME",1,1
20
.
.
REST OF BASIC PROGRAM
3) EDITOR/ASSEMBLER PACKAGE:
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
D6510 0000 0 6510 On-Chip Data-Direction Register
R6510 0001 1 6510 On-Chip 8-Bit Input/Output Register
0002 2 Unused
ADRAY1 0003-0004 3-4 Jump Vector: Convert Floating-Integer
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
HEX DECIMAL
LABEL ADDRESS LOCATION DESCRIPTION
-------------------------------------------------------------------------
CHAPTER 6
INPUT/OUTPUT
GUIDE
o Introduction
o Output to the TV
o Output to Other Devices
o The Game Ports
o RS-232 Interface Description
o The User Port
o The Serial Bus
o The Expansion Port
o Z-80 Microprocessor Cartridge
335
~
INTRODUCTION
Computers have three basic abilities: they can calculate, make deci-
sions, and communicate. Calculation is probably the easiest to program.
Most of the rules of mathematics are familiar to us. Decision making is
not too difficult, since the rules of logic are relatively few, even if
you don't know them too well yet.
Communication is the most complex, because it involves the least
exacting set of rules. This is not an oversight in the design of
computers. The rules allow enough flexibility to communicate virtually
anything, and in many possible ways. The only real rule is this: whatever
sends information must present the information so that it can be
understood by the receiver.
OUTPUT TO THE TV
The simplest form of output in BASIC is the PRINT statement. PRINT uses
the TV screen as the output device, and your eyes are the input device
because they use the information on the screen.
When PRINTing on the screen, your main objective is to format the
information on the screen so it's easy to read. You should try to think
like a graphic artist, using colors, placement of letters, capital and
lower case letters, as well as graphics to best communicate the
information. Remember, no matter how smart your program, you want to be
able to understand what the results mean to you.
The PRINT statement uses certain character codes as "commands" to the
cursor. The <CRSR> key doesn't actually display anything, it just makes
the cursor change position. Other commands change colors, clear the
screen, and insert or delete spaces. The <RETURN> key has a character
code number (CHR$) of 13. A complete table of these codes is contained in
Appendix C.
There are two functions in the BASIC language that work with the PRINT
statement. TAB positions the,cursor on the given position from the left
edge of the screen, SPC moves the cursor right a given number of spaces
from the current position.
Punctuation marks in the PRINT statement serve to separate and format
information. The semicolon (;) separates 2 items without any spaces in
between. If it is the last thing on a line, the cursor remains after the
last thing PRINTed instead of going down to the next line. It suppresses
The OPEN statement is somewhat different for each device. The pa-
rameters in the OPEN statement are shown in the table below for each
device.
+--------+---------+---------------------+------------------------------+
| DEVICE | DEVICE# | NUMBER | STRING |
+--------+---------+---------------------+------------------------------+
|CASSETTE| 1 | 0 = Input | File Name |
| | | 1 = Output | |
| | | 2 = Output with EOT | |
| MODEM | 2 | 0 | Control Registers |
| SCREEN | 3 | 0,1 | |
| PRINTER| 4 or 5 | 0 = Upper/Graphics | Text Is PRINTed |
| | | 7 = Upper/Lower Case| |
| DISK | 8 to 11 | 2-14 = Data Channel | Drive #, File Name |
| | | | File Type, Read/Write |
| | | 15 = Command | Command |
| | | Channel | |
+--------+---------+---------------------+------------------------------+
OUTPUT TO PRINTER
The printer is an output device similar to the screen. Your main con-
cern when sending output to the printer is to create a format that is
easy on the eyes. Your tools here include reversed, double-width, capital
and lower case letters, as well as dot-programmable graphics.
The SPC function works for the printer in the same way it works for the
screen. However, the TAB function does not work correctly on the printer,
because it calculates the current position on the line based on the
cursor's position on the screen, not on the paper.
The OPEN statement for the printer creates the channel for communi-
cation. It also specifies which character set will be used, either upper
case with graphics or upper and lower case.
When working with one character set, individual lines can be PRINTed
in the opposite character set. When in upper case with graphics, the
cursor down character (CHR$(17)) switches the characters to the upper
and lower case set. When in upper and lower case, the cursor up char-
acter (CHR$(145)) allows upper case and graphics characters to be
PRINTed.
Other special functions in the printer are controlled through character
codes. All these codes are simply PRINTed just like any other character.
OUTPUT TO MODEM
The modem is a simple device that can translate character codes into
audio pulses and vice-versa, so that computers can communicate over
telephone lines. The OPEN statement for the modem sets up the parameters
to match the speed and format of the other computer you are communicating
with. Two characters can be sent in the string at the end
of the OPEN statement.
The bit positions of the first character code determine the baud rate,
number of data bits, and number of stop bits. The second code is op-
tional, and its bits specify the parity and duplex of the transmission.
See the RS-232 section or your VICMODEM manual for specific details on
this device.
Most computers use the American Standard Code for Information In-
terchange, known as ASCII (pronounced ASK-KEY). This standard set of
character codes is somewhat different from the codes used in the Com-
modore 64. When communicating with other computers, the Commodore
character codes must be translated into their ASCII counterparts. A table
of standard ASCII codes is included in this book in Appendix C.
Output to the modem is a fairly uncomplicated task, aside from the need
for character translation. However, you must know the receiving device
fairly well, especially when writing programs where your computer "talks"
to another computer without human intervention. An example of this would
be a terminal program that automatically types in your account number and
secret password. To do this successfully, you must carefully count the
number of characters and RETURN characters. Otherwise, the computer
receiving the characters won't know what to do with them.
Cassette tapes have an almost unlimited capacity for data. The longer
the tape, the more information it can store. However, tapes are limited
in time. The more data on the tape, the longer the time it takes to find
the information.
The programmer must try to minimize the time factor when working with
tape storage. One common practice is to read the entire cassette data
file into RAM, then process it, and then re-write all the data on the
tape. This allows you to sort, edit, and examine your data. However, this
limits the size of your files to the amount of available RAM.
If your data file is larger than the available RAM, it is probably time
to switch to using the floppy disk. The disk can read data at any
position on the disk, without needing to read through all the other data.
You can write data over old data without disturbing the rest of the file.
That's why the disk is used for all business applications like ledgers
and mailing lists.
The PRINT# statement formats data just like the PRINT statement does.
All punctuation works the same. But remember, you're not working with the
screen now. The formatting must be done with the INPUT# statement
constantly in mind.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
D O G C A T T R E E RETURN
The INPUT# statement works like the regular INPUT statement. When
typing data into the INPUT statement, the data items are separated,
either by hitting the <RETURN> key or using commas to separate them. The
PRINT# statement puts a RETURN at the end of a line just like the PRINT
statement. A$ fills up with all three values because there's no separator
on the tape between them, only after all three.
A proper separator would be a comma (,) or a RETURN on the tape. The
RETURN code is automatically put at the end of a PRINT or PRINT#
statement. One way to put the RETURN code between each item is to us only
one item per PRINT# statement. A better way is to set a variable to the
RETURN CHR$ code, which is CHR$(13), or use a comma. The statement for
this is R$=",":PRINT#1, A$ R$ B$ R$ C$. Don't use commas or any other
punctuation between the variable names, since the Commodore 64 can tell
them apart and they'll only use up space in your program.
A proper tape file looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
D O G , C A T , T R E E RETURN
The GET# statement will pick data from the tape one character at a
time. It will receive each character, including the RETURN code and other
punctuation. The CHR$(0) code is received as an empty string, not as a
one character string with a code of 0. If you try to use the ASC function
on an empty string, you get the error message ILLEGAL QUANTITY ERROR.
The Commodore 64 has two 9-pin Game Ports which allow the use of
joysticks, paddies, or a light pen. Each port will accept either one joy-
stick or one paddle pair. A light pen can be plugged into Port A (only)
for special graphic control, etc. This section gives you examples of how
to use the joysticks and paddies from both BASIC and machine language.
The digital joystick is connected to CIA #1 (MOS 6526 Complex Interface
Adapter). This input/output device also handles the paddle fire buttons
and keyboard scanning. The 6526 CIA chip has 16 registers which are in
memory locations 56320 through 56335 inclusive ($DC00 to $DC0F). Port A
data appears at location 56320 (DC00) and Port B data is found at
location 56321 ($DC01).
A digital joystick has five distinct switches, four of the switches are
used for direction and one of the switches is used for the fire button.
The joystick switches are arranged as shown:
(Top)
FIRE
(Switch 4)
UP
(Switch 0)
|
|
|
LEFT | RIGHT
-------+-------
(Switch 2) | (Switch 3)
|
|
|
DOWN
(Switch 1)
+-----------------------------------------------------------------------+
| NOTE: For the second joystick, set JV = PEEK (56321). |
+-----------------------------------------------------------------------+
+-------------+---------------+
| JV EQUAL TO | DIRECTION |
+-------------+---------------+
| 0 | NONE |
| 1 | UP |
| 2 | DOWN |
| 3 | - |
| 4 | LEFT |
| 5 | UP & LEFT |
| 6 | DOWN & LEFT |
| 7 | - |
| 8 | RIGHT |
| 9 | UP & RIGHT |
| 10 | DOWN & RIGHT |
+-------------+---------------+
* = $c200
PADDLES
A paddle is connected to both CIA #1 and the SID chip (MOS 6581 Sound
Interface Device) through a game port. The paddle value is read via the
SID registers 54297 ($D419) and 54298 ($D41A). PADDLES ARE NOT RELIABLE
WHEN READ FROM BASIC ALONE!!!! The best way to use paddles, from BASIC or
machine code, is to use the following machine language routine... (SYS to
it from BASIC then PEEK the memory locations used by the subroutine).
*=$c100
buffer *=*+1
pdlx *=*+2
pdly *=*+2
btna *=*+1
btnb *=*+1
* = $c000
LIGHT PEN
The light pen input latches the current screen position into a pair of
registers (LPX, LPY) on a low-going edge. The X position register 19
($13) will contain the 8 MSB of the X position at the time of transition.
Since the X position is defined by a 512-state counter (9 bits),
resolution to 2 horizontal dots is provided. Similarly, the Y position is
latched in its register 20 ($14), but here 8 bits provide single raster
resolution within the visible display. The light pen latch may be
triggered only once per frame, and subsequent triggers within the same
frame will have no effect. Therefore, you must take several samples
before turning the pen to the screen (3 or more samples average),
depending upon the characteristics of your light pen.
Only one RS-232 channel should be open at any time; a second OPEN
statement will cause the buffer pointers to be reset. Any characters in
either the transmit buffer or the receive buffer will be lost.
Up to 4 characters can be sent in the filename field. The first two are
the control and command register characters; the other two are reserved
for future system options. Baud rate, parity, and other options can be
selected through this feature.
No error-checking is done on the control word to detect a non-
implemented baud rate. Any illegal control word will cause the system
output to operate at a very slow rate (below 50 baud).
BASIC SYNTAX:
+-+-+-+-+-+-+-+-+
|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
PARITY OPTIONS ----+-+-+ | | | | +----- HANDSHAKE
+---+---+---+---------------------+| | | |
|BIT|BIT|BIT| OPERATIONS || | | | 0 - 3-LINE
| 7 | 6 | 5 | || | | | 1 - X-LINE
+---+---+---+---------------------+| | | |
| - | - | 0 |PARITY DISABLED, NONE|| | | |
| | | |GENERATED/RECEIVED || | | |
+---+---+---+---------------------+| | | +------- UNUSED
| 0 | 0 | 1 |ODD PARITY || | +--------- UNUSED
| | | |RECEIVER/TRANSMITTER || +----------- UNUSED
+---+---+---+---------------------+|
| 0 | 1 | 1 |EVEN PARITY ||
| | | |RECEIVER/TRANSMITTER |+------------- DUPLEX
+---+---+---+---------------------+
| 1 | 0 | 1 |MARK TRANSMITTED | 0 - FULL DUPLEX
| | | |PARITY CHECK DISABLED| 1 - HALF DUPLEX
+---+---+---+---------------------+
| 1 | 1 | 1 |SPACE TRANSMITTED |
| | | |PARITY CHECK DISABLED|
+---+---+---+---------------------+
KERNAL ENTRY:
+-----------------------------------------------------------------------+
| IMPORTANT NOTE: In a BASIC program, the RS-232 OPEN command should be |
| performed before creating any variables or arrays because an automatic|
| CLR is performed when an RS-232 channel is OPENed (This is due to the |
| allocation of 512 bytes at the top of memory.) Also remember that your|
| program will be destroyed if 512 bytes of space are not available at |
| the time of the OPEN statement. |
+-----------------------------------------------------------------------+
BASIC SYNTAX:
KERNAL ENTRIES:
CHKIN ($FFC6)-See Memory Map for more information on entry and exit
conditions.
GETIN ($FFE4)-See Memory Map for more information on entry and exit
conditions.
CHRIN ($FFCF)-See Memory Map for more information on entry and exit
conditions.
+-----------------------------------------------------------------------+
| NOTES: |
| If the word length is less than 8 bits, all unused bit(s) will be |
| assigned a value of zero. |
| If a GET# does not find any data in the buffer, the character "" (a |
| null) is returned. |
| If INPUT# is used, then the system will hang in a waiting condition |
| until a non-null character and a following carriage return is |
| received. Therefore, if the Clear To Send (CTS) or Data Set Ready |
| (DSR) line(s) disappear during character INPUT#, the system will hang |
| in a RESTORE-only state. This is why the INPUT# and CHRIN routines are|
| NOT recommended. |
| The routine CHKIN handles the x-line handshake which follows the EIA|
| standard (August 1979) for RS-232-C interfaces. (The Request To Send |
| (RTS), CTS, and Received line signal (DCD) lines are implemented with |
| the Commodore 64 computer defined as the Data Terminal device.) |
+-----------------------------------------------------------------------+
When sending data, the output buffer can hold 255 characters before a
full buffer hold-off occurs. The system will wait in the CHROUT routine
until transmission is allowed or the <RUN/STOP> and <RESTORE> keys are
used to recover the system through a WARM START.
BASIC SYNTAX:
KERNAL ENTRIES:
CHKOUT ($FFC9)-See Memory Map for more information on entry and exit
conditions.
CHROUT ($FFD2)-See Memory Map for more information on entry conditions.
+-----------------------------------------------------------------------+
| IMPORTANT NOTES: There is no carriage-return delay built into the |
| output channel. This means that a normal RS-232 printer cannot |
| correctly print, unless some form of hold-off (asking the Commodore 64|
| to wait) or internal buffering is implemented by the printer. The |
| hold-off can easily be implemented in your program. If a CTS (x-line) |
| handshake is implemented, the Commodore 64 buffer will fill, and then |
| hold-off more output until transmission is allowed by the RS-232 |
| device. X-line handshaking is a handshake routine that uses multi- |
| lines for receiving and transmitting data. |
| The routine CHKOUT handles the x-line handshake, which follows the |
| EIA standard (August 1979) for RS-232-C interfaces. The RTS, CTS, and |
| DCD lines are implemented with the Commodore 64 defined as the Data |
| Terminal Device. |
+-----------------------------------------------------------------------+
Closing an RS-232 file discards all data in the buffers at the time of
execution (whether or not it had been transmitted or printed out), stops
all RS-232 transmitting and receiving, sets the RTS and transmitted data
(Sout) lines high, and removes both RS-232 buffers.
BASIC SYNTAX:
CLOSE lfn
KERNAL ENTRY:
CLOSE ($FFC3)-See Memory Map for more information on entry and exit
conditions.
+-----------------------------------------------------------------------+
| NOTE: Care should be taken to ensure all data is transmitted before |
| closing the channel. A way to check this from BASIC is: |
| |
| 100 SS=ST: IF(SS=0 OR SS=8) THEN 100 |
| 110 CLOSE lfn |
+-----------------------------------------------------------------------+
+-----------------------------------------------------------------------+
| NOTES: |
| If the BIT=0, then no error has been detected. |
| The RS-232 status register can be read from BASIC using the variable|
| ST. |
| If ST is read by BASIC or by using the KERNAL READST routine the |
| RS-232 status word is cleared when you exit. If multiple uses of the |
| STATUS word are necessary the ST should be assigned to another |
| variable. For example: |
| |
| SR=ST: REM ASSIGNS ST TO SR |
| |
| The RS-232 status is read (and cleared) only when the RS-232 channel|
| was the last external I/O used. |
+-----------------------------------------------------------------------+
The two locations above are set up by the OPEN KERNAL routine, each
pointing to a different 256-byte buffer. They are de-allocated by writing
a zero into the high order bytes ($00F8 and $00FA), which is done by the
CLOSE KERNAL entry. They may also be allocated/de-allocated by the
machine language programmer for his/her own purposes, removing/creating
only the buffer(s) required. When using a machine language program that
allocates these buffers, care must be taken to make sure that the top of
memory pointers stay correct, especially if BASIC programs are expected
to run at the same time.
INPUT/OUTPUT GUIDE 357
~
1 1 1
1 2 3 4 5 6 7 8 9 0 1 2
+--@-@-@-@-@-@-@-@-@-@-@-@--+
| |
+--@-@-@-@-@-@-@-@-@-@-@-@--+
A B C D E F H J K L M N
The DATA DIRECTION REGISTER has its location at 56579 ($DD03 hex). Each
of the eight lines in the PORT has a BIT in the eight-bit DATA DIRECTION
REGISTER (DDR) which controls whether that line will be an input or an
output. If a bit in the DDR is a ONE, the corresponding line of the PORT
will be an OUTPUT. If a bit in the DDR is a ZERO, the corresponding line
of the PORT will be an INPUT. For example, if bit 3 of the DDR is set to
1, then line 3 of the PORT will be an output. A further example:
If the DDR is set like this:
BIT #: 7 6 5 4 3 2 1 0
VALUE: 0 0 1 1 1 0 0 0
You can see that lines 5,4, and 3 will be outputs since those bits are
ones. The rest of the lines will be inputs, since those lines are zeros.
To PEEK or POKE the USER port, it is necessary to use both the DDR and
the PORT itself.
Remember that the PEEK and POKE statements want a number from 0-255.
The numbers given in the example must be translated into decimal before
they can be used. The value would be:
Notice that the bit # for the DDR is the same number that = 2 raised to
a power to turn the bit value on.
The two other lines, FLAG1 and PA2 are different from the rest of the
USER PORT. These two lines are mainly for HANDSHAKING, and are programmed
differently from port B.
Handshaking is needed when two devices communicate. Since one device
may run at a different speed than another device it is necessary to give
the devices some way of knowing what the other device is doing. Even when
the devices are operating at the same speed, handshaking is necessary to
let the other know when data is to be sent, and if it has been received.
The FLAG1 line has special characteristics which make it well suited for
handshaking.
FLAG1 is a negative edge sensitive input which can be used as a general
purpose interrupt input. Any negative transition on the FLAG line will
set the FLAG interrupt bit. If the FLAG interrupt is enabled, this will
The serial bus is a daisy chain arrangement designed to let the Com-
modore 64 communicate with devices such as the VIC-1541 DISK DRIVE and
the VIC-1525 GRAPHICS PRINTER. The advantage of the serial bus is that
more than one device can be connected to the port. Up to 5 devices can be
connected to the serial bus at one time.
There are three types of operation over a serial bus-CONTROL, TALK, and
LISTEN. A CONTROLLER device is one which controls operation of the serial
bus. A TALKER transmits data onto the bus. A LISTENER receives data from
the bus.
The Commodore 64 is the controller of the bus. It also acts as a TALKER
(when sending data to the printer, for example) and as a LISTENER (when
loading a program from the disk drive, for example). Other devices may be
either LISTENERS (the printer), TALKERS, or both (the disk drive). Only
the Commodore 64 can act as the controller.
All devices connected on the serial bus will receive all the data
transmitted over the bus. To allow the Commodore 64 to route data to its
intended destination, each device has a bus ADDRESS. By using this device
address, the Commodore 64 can control access to the bus. Addresses on the
serial bus range from 4 to 31.
The Commodore 64 can COMMAND a particular device to TALK or LISTEN.
When the Commodore 64 commands a device to TALK, the device will begin
putting data onto the serial bus. When the Commodore 64 commands a device
to LISTEN, the device addressed will get ready to receive data (from the
Commodore 64 or from another device on the bus). Only one device can TALK
on the bus at a time; otherwise, the data will collide and the system
will crash in confusion. However, any number of devices can LISTEN at the
same time to one TALKER.
OPEN 1,4,7
where,
1 is the logical file number (the number you PRINT# to),
4 is the ADDRESS of the printer, and
7 is the SECONDARY ADDRESS that tells the printer to go into UPPER/
LOWER case mode.
There are 6 lines used in serial bus operations - input and 3 output.
The 3 input lines bring data, control, and timing signals into the Com-
modore 64. The 3 output lines send data, control, and timing signals from
the Commodore 64 to external devices on the serial bus.
Serial I/O
++ ++
+-------+----------------------+ / +-+ \
| Pin | Type | /5 1\
+-------+----------------------+ + O O +
| 1 | /SERIAL SRQ IN | | 6 |
| 2 | GND | | O |
| 3 | SERIAL ATN OUT | | |
| 4 | SERIAL CLK IN/OUT | + O O +
| 5 | SERIAL DATA IN/OUT | \4 O 2/
| 6 | /RESET | \ 3 /
+-------+----------------------+ +---+
Any device on the serial bus can bring this signal LOW when it requires
attention from the Commodore 64. The Commodore 64 will then take care of
the device. (See Figure 6-4).
This signal is used for timing the data sent on the serial bus. (See
Figure 6-4).
Data on the serial bus is transmitted one bit at a time on this line.
(See Figure 6-4.)
+---------+---+---------------------------------------------------------+
| NAME |PIN| DESCRIPTION |
+---------+---+---------------------------------------------------------+
| /ROML |11 | 8K decoded RAM/ROM block @ $8000 (active low) buffered |
| | | ls ttl output |
| BA |12 | Bus available signal from the VIC-II chip unbuffered |
| | | 1 Is load max. |
| /DMA |13 | Direct memory access request line (active low input) |
| | | ls ttl input |
| D7 |14 | Data bus bit 7 \ |
| D6 |15 | Data bus bit 6 + |
| D5 |16 | Data bus bit 5 | |
| D4 |17 | Data bus bit 4 +- unbuffered, 1 ls ttl load max |
| D3 |18 | Data bus bit 3 +- |
| D2 |19 | Data bus bit 2 | |
| D1 |20 | Data bus bit 1 + |
| D0 |21 | Data bus bit 0 / |
| GND |22 | System ground |
| GND | A | |
| /ROMH | B | 8K decoded RAM/ROM block @ $E000 buffered |
| /RESET | C | 6502 RESET pin(active low) buff'ed ttl out/unbuff'ed in|
| /NMI | D | 6502 Non Maskable Interrupt (active low) buff'ed ttl |
| | | out, unbuff'ed in |
| 02 | E | Phase 2 system clock |
| A15 | F | Address bus bit 15 \ |
| A14 | H | Address bus bit 14 + |
| A13 | J | Address bus bit 13 | |
| A12 | K | Address bus bit 12 | |
| A11 | L | Address bus bit 11 | |
| A10 | M | Address bus bit 10 | |
| A9 | N | Address bus bit 9 | |
| A8 | P | Address bus bit 8 +-- unbuffered, 1 ls ttl load max |
| A7 | R | Address bus bit 7 +-- |
| A6 | S | Address bus bit 6 | |
| A5 | T | Address bus bit 5 | |
| A4 | U | Address bus bit 4 | |
| A3 | V | Address bus bit 3 | |
| A2 | W | Address bus bit 2 | |
| A1 | X | Address bus bit 1 + |
| A0 | Y | Address bus bit 0 / |
| GND | Z | System ground |
+---------+---+---------------------------------------------------------+
Reading this book and using your computer has shown you just how
versatile your Commodore 64 really is. But what makes this machine even
more capable of meeting your needs is the addition of peripheral
equipment. Peripherals are things like Datassette(TM) recorders, disk
drives, printers, and modems. All these items can be added to your
Commodore 64 through the various ports and sockets on the back of your
machine. The thing that makes Commodore peripherals so good is the fact
that our peripherals are "intelligent." That means that they don't take
up valuable Random Access Memory space when they're in use. You're free
to use all 64K of memory in your Commodore 64.
Another advantage of your Commodore 64 is the fact most programs you
write on your Commodore 64 today will be upwardly compatible with any new
Commodore computer you buy in the future. This is partially because of
the qualities of the computer's Operating System (OS).
However, there is one thing that the Commodore OS can't do: make your
programs compatible with a computer made by another company.
Most of the time you won't even have to think about using another com-
pany's computer, because your Commodore 64 is so easy to use. But for the
occasional user who wants to take advantage of software that may not be
available in Commodore 64 format we have created a Commodore CP/M(R)
cartridge.
CP/M(R) is not a "computer dependent" operating system. Instead it uses
some of the memory space normally available for programming to run its
own operating system. There are advantages and disadvantages to this. The
disadvantages are that the programs you write will have to be shorter
than the programs you can write using the Commodore 64's built-in
operating system. In addition, you can NOT use the Commodore 64's
powerful screen editing capabilities. The advantages are that you can now
use a large amount of software that has been specifically designed for
CP/M(R) and the Z-80 microprocessor, and the programs that you write
using the CP/M(R) operating system can be transported and run on any
other computer that has CP/M(R) and a Z-80 card.
By the way, most computers that have a Z-80 microprocessor require that
you go inside the computer to actually install a Z-80 card. With this
method you have to be very careful not to disturb the delicate circuitry
that runs the rest of the computer. The Commodore CP/M& cartridge
eliminates this hassle because our Z-80 cartridge plugs into the back of
your Commodore 64 quickly and easily, without any messy wires that can
cause problems later.
The Commodore Z-80 cartridge let's you run programs designed for a Z-80
microprocessor on your Commodore 64. The cartridge is provided with a
diskette containing the Commodore CP/M(R) operating system.
To run CP/M(R):
At this point the 64K bytes of RAM in the Commodore 64 are accessible
by the built-in 6510 central processor, OR 48K bytes of RAM are available
for the Z-80 central processor. You can shift back and forth between
these two processors, but you can NOT use them at the same time in a
single program. This is possible because of your Commodore 64's
sophisticated timing mechanism.
Below is the memory address translation that is performed on the Z-80
cartridge. You should notice that by adding 4096 bytes to the memory
locations used in CP/M(R) $1000 (hex) you equal the memory addresses of
the normal Commodore 64 operating system. The correspondence between Z-80
and 6510 memory addresses is as follows:
+-----------------------------------+-----------------------------------+
| Z-80 ADDRESSES | 6510 ADDRESSES |
+-----------------+-----------------+-----------------+-----------------+
| DECIMAL | HEX | DECIMAL | HEX |
+-----------------+-----------------+-----------------+-----------------+
| 0000-4095 | 0000-0FFF | 4096-8191 | 1000-1FFF |
| 4096-8191 | 1000-1FFF | 8192-12287 | 2000-2FFF |
| 8192-12287 | 2000-2FFF | 12288-16383 | 3000-3FFF |
| 12288-16383 | 3000-3FFF | 16384-20479 | 4000-4FFF |
| 16384-20479 | 4000-4FFF | 20480-24575 | 5000-5FFF |
| 20480-24575 | 5000-5FFF | 24576-28671 | 6000-6FFF |
| 24576-28671 | 6000-6FFF | 28672-32767 | 7000-7FFF |
| 28672-32767 | 7000-7FFF | 32768-36863 | 8000-SFFF |
| 32768-36863 | 8000-8FFF | 36864-40959 | 9000-9FFF |
| 36864-40959 | 9000-9FFF | 40960-45055 | A000-AFFF |
| 40960-45055 | A000-AFFF | 45056-49151 | B000-BFFF |
| 45056-49151 | B000-BFFF | 49152-53247 | C000-CFFF |
| 49152-53247 | C000-CFFF | 53248-57343 | D000-DFFF |
| 53248-57343 | D000-DFFF | 57344-61439 | E000-EFFF |
| 57344-61439 | E000-EFFF | 61440-65535 | F000-FFFF |
| 61440-65535 | F000-FFFF | 0000-4095 | 0000-0FFF |
+-----------------+-----------------+-----------------+-----------------+
To TURN ON the Z-80 and TURN OFF the 6510 chip, type in the following
program:
For more details about Commodore CP/M(R) and the Z-80 microprocessor
look for the cartridge and the Z-80 Reference Guide at your local
Commodore computer dealer.
INPUT/OUTPUT GUIDE 371
~~
APPENDICES
373
~
APPENDIX A
ABBREVIATIONS FOR BASIC KEYWORDS
374 APPENDIX A
~
APPENDIX A 375
~
APPENDIX B
The following chart lists all of the characters built into the
Commodore 64 character sets. It shows which numbers should be POKED into
screen memory (locations 1024-2023) to get a desired character. Also
shown is which character corresponds to a number PEEKed from the screen.
Two character sets are available, but only one set at a time. This
means that you cannot have characters from one set on the screen at the
same time you have characters from the other set displayed. The sets are
switched by holding down the <SHIFT> and <C=> keys simultaneously.
From BASIC, POKE 53272,21 will switch to upper case mode and
POKE 53272,23 switches to lower case.
Any number on the chart may also be displayed in REVERSE. The reverse
character code may be obtained by adding 128 to the values shown.
If you want to display a solid circle at location 1504, POKE the code
for the circle (81) into location 1504: POKE 1504,81.
There is a corresponding memory location to control the color of each
character displayed on the screen (locations 55296-56295). To change the
color of the circle to yellow (color code 7) you would POKE the corre-
sponding memory location (55776) with the character color: POKE 55776,7.
Refer to Appendix D for the complete screen and color memory maps,
along with color codes.
+-----------------------------------------------------------------------+
| NOTE: The following POKEs display the same symbol in set 1 and 2: 1, |
| 27-64, 91-93, 96-104, 106-121, 123-127. |
+-----------------------------------------------------------------------+
SCREEN CODES
376 APPENDIX B
~
378 APPENDIX B
~
APPENDIX C
This appendix shows you what characters will appear if you PRINT
CHR$(X), for all possible values of X. It will also show the values ob-
tained by typing PRINT ASC("x"), where x is any character you can type.
This is useful in evaluating the character received in a GET statement,
converting upper/lower case, and printing character based commands (like
switch to upper/lower case) that could not be enclosed in quotes.
+-----------------+-----------------+-----------------+-----------------+
| PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ |
+-----------------+-----------------+-----------------+-----------------+
| 0 | {down} 17 | " 34 | 3 51 |
| 1 | {rvs on} 18 | # 35 | 4 52 |
| 2 | {home} 19 | $ 36 | 5 53 |
| 3 | {del} 20 | % 37 | 6 54 |
| 4 | 21 | & 38 | 7 55 |
| {white} 5 | 22 | ' 39 | 8 56 |
| 6 | 23 | ( 40 | 9 57 |
| 7 | 24 | ) 41 | : 58 |
| disSHIFT+C= 8 | 25 | * 42 | ; 59 |
| enaSHIFT+C= 9 | 26 | + 43 | < 60 |
| 10 | 27 | , 44 | = 61 |
| 11 | {red} 28 | - 45 | > 62 |
| 12 | {right} 29 | . 46 | ? 63 |
| return 13 | {green} 30 | / 47 | @ 64 |
| lower case 14 | {blue} 31 | 0 48 | A 65 |
| 15 | SPACE 32 | 1 49 | B 66 |
| 16 | ! 33 | 2 50 | C 67 |
APPENDIX C 379
~
+-----------------+-----------------+-----------------+-----------------+
| PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ |
+-----------------+-----------------+-----------------+-----------------+
| D 68 | 97 | 126 | {grey 3} 155 |
| E 69 | 98 | 127 | {purple} 156 |
| F 70 | 99 | 128 | {left} 157 |
| G 71 | 100 | {orange} 129 | {yellow} 158 |
| H 72 | 101 | 130 | {cyan} 159 |
| I 73 | 102 | 131 | SPACE 160 |
| J 74 | 103 | 132 | 161 |
| K 75 | 104 | f1 133 | 162 |
| L 76 | 105 | f3 134 | 163 |
| M 77 | 106 | f5 135 | 164 |
| N 78 | 107 | f7 136 | 165 |
| O 79 | 108 | f2 137 | 166 |
| P 80 | 109 | f4 138 | 167 |
| Q 81 | 110 | f6 139 | 168 |
| R 82 | 111 | f8 140 | 169 |
| S 83 | 112 |shift+ret. 141 | 170 |
| T 84 | 113 |upper case 142 | 171 |
| U 85 | 114 | 143 | 172 |
| V 86 | 115 | {black} 144 | 173 |
| W 87 | 116 | {up} 145 | 174 |
| X 88 | 117 | {rvs off} 146 | 175 |
| Y 89 | 118 | {clear} 147 | 176 |
| Z 90 | 119 | {inst} 148 | 177 |
| [ 91 | 120 | {brown} 149 | 178 |
| pound 92 | 121 | {lt. red} 150 | 179 |
| ] 93 | 122 | {grey 1} 151 | 180 |
| ^ 94 | 123 | {grey 2} 152 | 181 |
|{arrow left}95 | 124 | {lt.green}153 | 182 |
| 96 | 125 | {lt.blue} 154 | 183 |
380 APPENDIX C
~
+-----------------+-----------------+-----------------+-----------------+
| PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ | PRINTS CHR$ |
+-----------------+-----------------+-----------------+-----------------+
| 184 | 186 | 188 | 190 |
| 185 | 187 | 189 | 191 |
+-----------------+-----------------+-----------------+-----------------+
APPENDIX D
The following charts list which memory locations control placing char-
acters on the screen, and the locations used to change individual char-
acter colors, as well as showing character color codes.
COLUMN 1063
0 10 20 30 39 /
+------------------------------------------------------------/
1024 | | 0
1064 | |
1104 | |
1144 | |
1184 | |
1224 | |
1264 | |
1304 | |
1344 | |
1384 | |
1424 | | 10
1464 | |
1504 | | ROW
1544 | |
1584 | |
1624 | |
1664 | |
1704 | |
1744 | |
1784 | |
1824 | | 20
1864 | |
1904 | |
1944 | |
1984 | | 24
+------------------------------------------------------------\
\
2023
382 APPENDIX D
~
APPENDIX E
This appendix contains a complete list of Note#, actual note, and the
values to be POKED into the HI FREQ and LOW FREQ registers of the sound
chip to produce the indicated note.
+-----------------------------+-----------------------------------------+
| MUSICAL NOTE | OSCILLATOR FREQ |
+-------------+---------------+-------------+-------------+-------------+
| NOTE | OCTAVE | DECIMAL | HI | LOW |
+-------------+---------------+-------------+-------------+-------------+
| 0 | C-0 | 268 | 1 | 12 |
| 1 | C#-0 | 284 | 1 | 28 |
| 2 | D-0 | 301 | 1 | 45 |
| 3 | D#-0 | 318 | 1 | 62 |
| 4 | E-0 | 337 | 1 | 81 |
| 5 | F-0 | 358 | 1 | 102 |
| 6 | F#-0 | 379 | 1 | 123 |
| 7 | G-0 | 401 | 1 | 145 |
| 8 | G#-0 | 425 | 1 | 169 |
| 9 | A-0 | 451 | 1 | 195 |
| 10 | A#-0 | 477 | 1 | 221 |
| 11 | B-0 | 506 | 1 | 250 |
| 16 | C-1 | 536 | 2 | 24 |
| 17 | C#-1 | 568 | 2 | 56 |
| 18 | D-1 | 602 | 2 | 90 |
| 19 | D#-1 | 637 | 2 | 125 |
| 20 | E-1 | 675 | 2 | 163 |
| 21 | F-1 | 716 | 2 | 204 |
| 22 | F#-1 | 758 | 2 | 246 |
| 23 | G-1 | 803 | 3 | 35 |
| 24 | G#-1 | 851 | 3 | 83 |
| 25 | A-1 | 902 | 3 | 134 |
| 26 | A#-1 | 955 | 3 | 187 |
| 27 | B-1 | 1012 | 3 | 244 |
| 32 | C-2 | 1072 | 4 | 48 |
384 APPENDIX E
~
+-----------------------------+-----------------------------------------+
| MUSICAL NOTE | OSCILLATOR FREQ |
+-------------+---------------+-------------+-------------+-------------+
| NOTE | OCTAVE | DECIMAL | HI | LOW |
+-------------+---------------+-------------+-------------+-------------+
| 33 | C#-2 | 1136 | 4 | 112 |
| 34 | D-2 | 1204 | 4 | 180 |
| 35 | D#-2 | 1275 | 4 | 251 |
| 36 | E-2 | 1351 | 5 | 71 |
| 37 | F-2 | 1432 | 5 | 152 |
| 38 | F#-2 | 1517 | 5 | 237 |
| 39 | G-2 | 1607 | 6 | 71 |
| 40 | G#-2 | 1703 | 6 | 167 |
| 41 | A-2 | 1804 | 7 | 12 |
| 42 | A#-2 | 1911 | 7 | 119 |
| 43 | B-2 | 2025 | 7 | 233 |
| 48 | C-3 | 2145 | 8 | 97 |
| 49 | C#-3 | 2273 | 8 | 225 |
| 50 | D-3 | 2408 | 9 | 104 |
| 51 | D#-3 | 2551 | 9 | 247 |
| 52 | E-3 | 2703 | 10 | 143 |
| 53 | F-3 | 2864 | 11 | 48 |
| 54 | F#-3 | 3034 | 11 | 218 |
| 55 | G-3 | 3215 | 12 | 143 |
| 56 | G#-3 | 3406 | 13 | 78 |
| 57 | A-3 | 3608 | 14 | 24 |
| 58 | A#-3 | 3823 | 14 | 239 |
| 59 | B-3 | 4050 | 15 | 210 |
| 64 | C-4 | 4291 | 16 | 195 |
| 65 | C#-4 | 4547 | 17 | 195 |
| 66 | D-4 | 4817 | 18 | 209 |
| 67 | D#-4 | 5103 | 19 | 239 |
| 68 | E-4 | 5407 | 21 | 31 |
| 69 | F-4 | 5728 | 22 | 96 |
| 70 | F#-4 | 6069 | 23 | 181 |
| 71 | G-4 | 6430 | 25 | 30 |
| 72 | G#-4 | 6812 | 26 | 156 |
| 73 | A-4 | 7217 | 28 | 49 |
| 74 | A#-4 | 7647 | 29 | 223 |
| 75 | B-4 | 8101 | 31 | 165 |
| 80 | C-5 | 8583 | 33 | 135 |
| 81 | C#-5 | 9094 | 35 | 134 |
APPENDIX E 385
~
+-----------------------------+-----------------------------------------+
| MUSICAL NOTE | OSCILLATOR FREQ |
+-------------+---------------+-------------+-------------+-------------+
| NOTE | OCTAVE | DECIMAL | HI | LOW |
+-------------+---------------+-------------+-------------+-------------+
| 82 | D-5 | 9634 | 37 | 162 |
| 83 | D#-5 | 10207 | 39 | 223 |
| 84 | E-5 | 10814 | 42 | 62 |
| 85 | F-5 | 11457 | 44 | 193 |
| 86 | F#-5 | 12139 | 47 | 107 |
| 87 | G-5 | 12860 | 50 | 60 |
| 88 | G#-5 | 13625 | 53 | 57 |
| 89 | A-5 | 14435 | 56 | 99 |
| 90 | A#-5 | 15294 | 59 | 190 |
| 91 | B-5 | 16203 | 63 | 75 |
| 96 | C-6 | 17167 | 67 | 15 |
| 97 | C#-6 | 18188 | 71 | 12 |
| 98 | D-6 | 19269 | 75 | 69 |
| 99 | D#-6 | 20415 | 79 | 191 |
| 100 | E-6 | 21629 | 84 | 125 |
| 101 | F-6 | 22915 | 89 | 131 |
| 102 | F#-6 | 24278 | 94 | 214 |
| 103 | G-6 | 25721 | 100 | 121 |
| 104 | G#-6 | 27251 | 106 | 115 |
| 105 | A-6 | 28871 | 112 | 199 |
| 106 | A#-6 | 30588 | 119 | 124 |
| 107 | B-6 | 32407 | 126 | 151 |
| 112 | C-7 | 34334 | 134 | 30 |
| 113 | C#-7 | 36376 | 142 | 24 |
| 114 | D-7 | 38539 | 150 | 139 |
| 115 | D#-7 | 40830 | 159 | 126 |
| 116 | E-7 | 43258 | 168 | 250 |
| 117 | F-7 | 45830 | 179 | 6 |
| 118 | F#-7 | 48556 | 189 | 172 |
| 119 | G-7 | 51443 | 200 | 243 |
| 120 | G#-7 | 54502 | 212 | 230 |
| 121 | A-7 | 57743 | 225 | 143 |
| 122 | A#-7 | 61176 | 238 | 248 |
| 123 | B-7 | 64814 | 253 | 46 |
+-------------+---------------+-------------+-------------+-------------+
386 APPENDIX E
~
FILTER SETTINGS
+------------+--------------------------------+
| Location | Contents |
+------------+--------------------------------+
| 54293 | Low cutoff frequency (0-7) |
| 54294 | High cutoff frequency (0-255) |
| 54295 | Resonance (bits 4-7) |
| | Filter voice 3 (bit 2) |
| | Filter voice 2 (bit 1) |
| | Filter voice 1 (bit 0) |
| 54296 | High pass (bit 6) |
| | Bandpass (bit 5) |
| | Low pass (bit 4) |
| | Volume (bits 0-3) |
+------------+--------------------------------+
APPENDIX E 387
~
APPENDIX F
BIBLIOGRAPHY
Cowbay Computing "Feed Me, I'm Your PET Computer", Carol Alexander
Hoyden Book Co. "BASIC From the Ground Up", David E. Simon
388 APPENDIX F
~
Little, Brown & Co. "Computer Games for Businesses, Schools, and
Homes", J. Victor Nagigian, and William S. Hodges
APPENDIX F 389
~
390 APPENDIX F
~
APPENDIX G
APPENDIX G 391
~
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
|Register#| | | | | | | | | |
| Dec Hex | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 15 F | S7Y7| | | | | | | S7Y0| SPRITE 7 Y |
| | | | | | | | | | Component |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 16 10 | S7X8| S6X8| S5X8| S4X8| S3X8| S2X8| S1X8| S0X8| MSB of X |
| | | | | | | | | | COORD. |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 17 11 | RC8 | ECM | BMM | BLNK| RSEL|YSCL2|YSCL1|YSCL0| Y SCROLL |
| | | | | | | | | | MODE |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 18 12 | RC7 | RC6 | RC5 | RC4 | RC3 | RC2 | RC1 | RC0 | RASTER |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 19 13 | LPX7| | | | | | | LPX0| LIGHT PEN X |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 20 14 | LPY7| | | | | | | | LIGHT PEN Y |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 21 15 | SE7 | | | | | | | SE0 |SPRITE ENABLE|
| | | | | | | | | | (ON/OFF) |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 22 16 | N.C.| N.C.| RST | MCM | CSEL|XSCL2|XSCL1|XSCL0| X SCROLL |
| | | | | | | | | | MODE |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 23 17 |SEXY7| | | | | | |SEXY0| SPRITE |
| | | | | | | | | | EXPAND Y |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 24 18 | VS13| VS12| VS11| VS10| CB13| CB12| CB11| N.C.| SCREEN and |
| | | | | | | | | | Character |
| | | | | | | | | | Memory Base |
| | | | | | | | | | Address |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 25 19 | IRQ | N.C.| N.C.| N.C.|LPIRQ| ISSC| ISBC| RIRQ| Interrupt |
| | | | | | | | | | Request's |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 26 1A | N.C.| N.C.| N.C.| N.C.| MLPI|MISSC|MISBC|MRIRQ| IRQ MASKS |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 27 1B | BSP7| | | | | | | BSP0| Background- |
| | | | | | | | | | Sprite |
| | | | | | | | | | PRIORITY |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
392 APPENDIX G
~
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
|Register#| | | | | | | | | |
| Dec Hex | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 | |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 28 1C | SCM7| | | | | | | SCM0| MULTICOLOR |
| | | | | | | | | |SPRITE SELECT|
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 29 1D |SEXX7| | | | | | |SEXX0| SPRITE |
| | | | | | | | | | EXPAND X |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 30 1E | SSC7| | | | | | | SSC0|Sprite-Sprite|
| | | | | | | | | | COLLISION |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
| 31 1F | SBC7| | | | | | | SBC0| Sprite- |
| | | | | | | | | | Background |
| | | | | | | | | | COLLISION |
+---------+-----+-----+-----+-----+-----+-----+-----+-----+-------------+
+---------+-----------------------+ +---------+-----------------------+
|Register#| | |Register#| |
| Dec Hex | Color | | Dec Hex | Color |
| 32 20 | BORDER COLOR | | 39 27 | SPRITE 0 COLOR |
| 33 21 | BACKGROUND COLOR 0 | | 40 28 | SPRITE 1 COLOR |
| 34 22 | BACKGROUND COLOR 1 | | 41 29 | SPRITE 2 COLOR |
| 35 23 | BACKGROUND COLOR 2 | | 42 2A | SPRITE 3 COLOR |
| 36 24 | BACKGROUND COLOR 3 | | 43 2B | SPRITE 4 COLOR |
| 37 25 | SPRITE MULTICOLOR 0 | | 44 2C | SPRITE 5 COLOR |
| 38 26 | SPRITE MULTICOLOR 1 | | 45 2D | SPRITE 6 COLOR |
+---------+-----------------------+ | 46 2E | SPRITE 7 COLOR |
COLOR CODES +---------+-----------------------+
+---------+-----------+ +---------+-----------+
| Dec Hex | Color | | Dec Hex | Color |
| 0 0 | BLACK | | 8 8 | ORANGE |
| 1 1 | WHITE | | 9 9 | BROWN |
| 2 2 | RED | | 10 A | LT RED |
| 3 3 | CYAN | | 11 B | GRAY 1 |
| 4 4 | PURPLE | | 12 C | GRAY 2 |
| 5 5 | GREEN | | 13 D | LT GREEN |
| 6 6 | BLUE | | 14 E | LT BLUE |
| 7 7 | YELLOW | | 15 F | GRAY 3 |
+---------+-----------+ +---------+-----------+
LEGEND: ONLY COLORS 0-7 MAY BE USED IN MULTICOLOR CHARACTER MODE
APPENDIX G 393
~
APPENDIX H
+------------------------------+----------------------------------------+
| FUNCTION | BASIC EQUIVALENT |
+------------------------------+----------------------------------------+
| SECANT | SEC(X)=1/COS(X) |
| COSECANT | CSC(X)=1/SIN(X) |
| COTANGENT | COT(X)=1/TAN(X) |
| INVERSE SINE | ARCSIN(X)=ATN(X/SQR(-X*X+1)) |
| INVERSE COSINE | ARCCOS(X)=-ATN(X/SQR(-X*X+1))+{pi}/2 |
| INVERSE SECANT | ARCSEC(X)=ATN(X/SQR(X*X-1)) |
| INVERSE COSECANT | ARCCSC(X)=ATN(X/SQR(X*X-1)) |
| | +(SGN(X)-1*{pi}/2 |
| INVERSE COTANGENT | ARCOT(X)=ATN(X)+{pi}/2 |
| HYPERBOLIC SINE | SINH(X)=(EXP(X)-EXP(-X))/2 |
| HYPERBOLIC COSINE | COSH(X)=(EXP(X)+EXP(-X))/2 |
| HYPERBOLIC TANGENT | TANH(X)=EXP(-X)/(EXP(X)+EXP(-X))*2+1 |
| HYPERBOLIC SECANT | SECH(X)=2/(EXP(X)+EXP(-X)) |
| HYPERBOLIC COSECANT | CSCH(X)=2/(EXP(X)-EXP(-X)) |
| HYPERBOLIC COTANGENT | COTH(X)=EXP(-X)/(EXP(X)-EXP(-X))*2+1 |
| INVERSE HYPERBOLIC SINE | ARCSINH(X)=LOG(X+SQR(X*X+1)) |
| INVERSE HYPERBOLIC COSINE | ARCCOSH(X)=LOG(X+SQR(X*X-1)) |
| INVERSE HYPERBOLIC TANGENT | ARCTANH(X)=LOG((1+X)/(1-X))/2 |
| INVERSE HYPERBOLIC SECANT | ARCSECH(X)=LOG((SQR(-X*X+1)+1/X) |
| INVERSE HYPERBOLIC COSECANT | ARCCSCH(X)=LOG((SGN(X)*SQR(X*X+1/X) |
| INVERSE HYPERBOLIC COTANGENT| ARCCOTH(X)=LOG((X+1)/(X-1))/2 |
+------------------------------+----------------------------------------+
394 APPENDIX H
~
APPENDIX I
PINOUTS FOR INPUT/OUTPUT DEVICES
Control Port 1
+-----+-------------+-----------+
| Pin | Type | Note | 1 2 3 4 5
| 1 | JOYA0 | | O O O O O
| 2 | JOYA1 | |
| 3 | JOYA2 | | O O O O
| 4 | JOYA3 | | 6 7 8 9
| 5 | POT AY | |
| 6 | BUTTON A/LP | |
| 7 | +5V | MAX. 50mA |
| 8 | GND | |
| 9 | POT AX | |
+-----+-------------+-----------+
Control Port 2
+-----+-------------+-----------+
| Pin | Type | Note |
| 1 | JOYB0 | |
| 2 | JOYB1 | |
| 3 | JOYB2 | |
| 4 | JOYB3 | |
| 5 | POT BY | |
| 6 | BUTTON B | |
| 7 | +5V | MAX. 50mA |
| 8 | GND | |
| 9 | POT BX | |
+-----+-------------+-----------+
APPENDIX I 395
~
Cassette
+-------+--------------------+
| Pin | Type |
+-------+--------------------+
| A-1 | GND | 1 2 3 4 5 6
| B-2 | +5V | +---@-@-@-@-@-@---+
| C-3 | CASSETTE MOTOR | | |
| D-4 | CASSETTE READ | +---@-@-@-@-@-@---+
| E-5 | CASSETTE WRITE | A B C D E F
| F-6 | CASSETTE SENSE |
+-------+--------------------+
User I/O
+-----+---------------+-----------+ +-----+---------------+-----------+
| Pin | Type | Note | | Pin | Type | Note |
+-----+---------------+-----------+ +-----+---------------+-----------+
| 1 | GND | | | A | GND | |
| 2 | +5V |MAX. 100 mA| | B | /FLAG2 | |
| 3 | /RESET | | | C | PB0 | |
| 4 | CNT1 | | | D | PB1 | |
| 5 | SP1 | | | E | PB2 | |
| 6 | CNT2 | | | F | PB3 | |
| 7 | SP2 | | | H | PB4 | |
| 8 | /PC2 | | | I | PB5 | |
| 9 | SER. ATN OUT | | | K | PB6 | |
| 10 | 9 VAC |MAX. 100 mA| | L | PB7 | |
| 11 | 9 VAC |MAX. 100 mA| | M | PA2 | |
| 12 | GND | | | N | GND | |
+-----+---------------+-----------+ +-----+---------------+-----------+
1 1 1
1 2 3 4 5 6 7 8 9 0 1 2
+--@-@-@-@-@-@-@-@-@-@-@-@--+
| |
+--@-@-@-@-@-@-@-@-@-@-@-@--+
A B C D E F H J K L M N
APPENDIX I 397
~
APPENDIX J
CONVERTING STANDARD
BASIC PROGRAMS TO
COMMODORE 64 BASIC
String Dimensions
Delete all statements that are used to declare the length of strings.
A statement such as DIM A$(I,J), which dimensions a string array for J
elements of length I, should be converted to the Commodore BASIC
statement DIM A$(J).
Some BASICs use a comma or an ampersand for string concatenation. Each
of these must be changed to a plus sign, which is the Commodore BASIC
operator for string concatenation.
In Commodore-64 BASIC, the MID$, RIGHT$, and LEFT$ functions are used
to take substrings of strings. Forms such as A$(I) to access the Ith
character in A$, or A$(I,J) to take a substring of A$ from position I to
J, must be changed as follows:
A$(I)=X$ A$=LEFT$(A$,I-1)+X$+MID$(A$,I+1)
A$(I,J)=X$ A$=LEFT$(A$,I-1)+X$+MID$(A$,J+1)
Multiple Assignments
To set B and C equal to zero, some BASICs allow statements of the form:
10 LET B=C=0
398 APPENDIX J
~
10 C=0:B=0
Multiple Statements
MAT Functions
APPENDIX J 399
~
APPENDIX K
ERROR MESSAGES
BAD DATA String data was received from an open file, but the
program was expecting numeric data.
BAD SUBSCRIPT The program was trying to reference an element of an
array whose number is outside of the range specified
in the DIM statement.
BREAK Program execution was stopped because you hit the
<STOP> key.
CAN'T CONTINUE The CONT command will not work, either because the
program was never RUN, there has been an error, or
a line has been edited.
DEVICE NOT PRESENT The required I/O device was not available for an
OPEN, CLOSE, CMD, PRINT#, INPUT#, or GET#.
DIVISION BY ZERO Division by zero is a mathematical oddity and not
allowed.
EXTRA IGNORED Too many items of data were typed in response to an
INPUT statement. Only the first few items were
accepted.
FILE NOT FOUND If you were looking for a file on tape, and END-OF-
TAPE marker was found. If you were looking on disk,
no file with that name exists.
FILE NOT OPEN The file specified in a CLOSE, CMD, PRINT#, INPUT#,
or GET#, must first be OPENed.
FILE OPEN An attempt was made to open a file using the number
of an already open file.
FORMULA TOO COMPLEX The string expression being evaluated should be split
into at least two parts for the system to work with,
or a formula has too many parentheses.
ILLEGAL DIRECT The INPUT statement can only be used within a pro-
gram, and not in direct mode.
ILLEGAL QUANTITY A number used as the argument of a function or
statement is out of the allowable range.
400 APPENDIX K
~
APPENDIX K 401
~
APPENDIX L
DESCRIPTION
402 APPENDIX L
~
PIN CONFIGURATION
+----+ +----+
01 IN 1 @| +-+ |@ 40 /RES
| |
RDY 2 @| |@ 39 02 IN
| |
/IRQ 3 @| |@ 38 R/W
| |
/NMI 4 @| |@ 37 D0
| |
AEC 5 @| |@ 36 D1
| |
VCC 6 @| |@ 35 D2
| |
A0 7 @| |@ 34 D3
| |
A1 8 @| |@ 33 D4
| |
A2 9 @| |@ 32 D5
| |
A3 10 @| |@ 31 D6
| 6510 |
A4 11 @| |@ 30 D7
| |
A5 12 @| |@ 29 P0
| |
A6 13 @| |@ 28 P1
| |
A7 14 @| |@ 27 P2
| |
A8 15 @| |@ 26 P3
| |
A9 16 @| |@ 25 P4
| |
A10 17 @| |@ 24 P5
| |
A11 18 @| |@ 23 A15
| |
A12 19 @| |@ 22 A14
| |
A13 20 @| |@ 21 GND
+-----------+
APPENDIX L 403
~
6510 CHARACTERISTICS
MAXIMUM RATINGS
+--------------------------+------------+-----------------+-------------+
| RATING | SYMBOL | VALUE | UNIT |
+--------------------------+------------+-----------------+-------------+
| SUPPLY VOLTAGE | Vcc | -0.3 to +7.0 | VDC |
| INPUT VOLTAGE | Vin | -0.3 to +7.0 | VDC |
| OPERATING TEMPERATURE | Ta | 0 to +70 | Celsius |
| STORAGE TEMPERATURE | Tstg | -55 to +150 | Celsius |
+--------------------------+------------+-----------------+-------------+
+-----------------------------------------------------------------------+
| NOTE: This device contains input protection against damage due to high|
| static voltages or electric fields; however, precautions should be |
| taken to avoid application of voltages higher than the maximum rating.|
+-----------------------------------------------------------------------+
+------------------------------------+--------+-------+---+-------+-----+
| CHARACTERISTIC | SYMBOL | MIN. |TYP| MAX. |UNIT |
+------------------------------------+--------+-------+---+-------+-----+
| Out Low Voltage | | | | | |
| (Iol=1.6mADC, Vcc=4.75V) | | | | | |
| Data, A0-A15, R/W, P0-P7 | Vol | - | - |Vss+0.4| VDC |
+------------------------------------+--------+-------+---+-------+-----+
| Power Supply Current | Icc | - |125| | mA |
+------------------------------------+--------+-------+---+-------+-----+
| Capacitance | C | | | | pF |
| Vin=0, Ta=25 Celsius, f=1MHz) | | | | | |
| Logic, P0-P7 | Cin | - | - | 10 | |
| Data | | - | - | 15 | |
| A0-A15, R/W | Cout | - | - | 12 | |
| 01 | C01 | - | 30| 50 | |
| 02 | C02 | - | 50| 80 | |
+------------------------------------+--------+-------+---+-------+-----+
CLOCK TIMING
406 APPENDIX L
~
CLOCK TIMING
[THE PICTURE IS MISSING!]
APPENDIX L 407
~
AC CHARACTERISTICS
408 APPENDIX L
~
+---------------------------------+------+----+---+---+---+---+---+-----+
| Delay Time, Address valid to | | | | | | | | |
| 02 positive transition | Taew | 180| - | - | | | | ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Delay Time, 02 positive | | | | | | | | |
| transition to Data valid on bus | Tedr | - | - |395| | | | ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Delay Time, data valid to 02 | | | | | | | | |
| negative transition | Tdsu | 300| - | - | | | | ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Delay Time, R/W negative | | | | | | | | |
| transition to 02 positive trans.| Twe | 130| - | - | | | | ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Delay Time, 02 negative trans. | | | | | | | | |
| to Peripheral data valid | Tpdw | - | - | 1 | | | | us |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Peripheral Data Setup Time | Tpdsu| 300| - | - | | | | ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
| Address Enable Setup Time | Taes | | | 60| | | 60| ns |
+---------------------------------+------+----+---+---+---+---+---+-----+
APPENDIX L 409
~
SIGNAL DESCRIPTION
These outputs are TTL compatible, capable of driving one standard TTL
load and 130 pf.
Eight pins are used for the data bus. This is a Bi-Directional bus,
transferring data to and from the device and peripherals. The outputs are
tri-state buffers capable of driving one standard TTL load and 130 pf.
Reset
This TTL level input requests that an interrupt sequence begin within
the microprocessor. The microprocessor will complete the current in-
struction being executed before recognizing the request. At that time,
the interrupt mask bit in the Status Code Register will be examined. If
the interrupt mask flag is not set, the microprocessor will begin an
410 APPENDIX L
~
interrupt sequence. The Program Counter and Processor Status Register are
stored in the stack. The microprocessor will then set the interrupt mask
flag high so that no further interrupts may occur. At the end of this
cycle, the program counter low will be loaded from address FFFE, and
program counter high from location FFFF, therefore transferring program
control to the memory vector located at these addresses.
The Address Bus is valid only when the Address Enable Control line is
high. When low, the Address Bus is in a high-impedance state. This
feature allows easy DMA and multiprocessor systems.
Six pins are used for the peripheral port, which can transfer data to
or from peripheral devices. The Output Register is located in RAM at
address 0001, and the Data Direction Register is at Address 0000. The
outputs are capable at driving one standard TTL load and 130 pf.
Read/Write (R/W)
ADDRESSING MODES
ZERO PAGE ADDRESSING - The zero page instructions allow for shorter code
APPENDIX L 411
~
and execution times by only fetching the second byte of the instruction
and assuming a zero high address byte. Careful use of the zero page can
result in significant increase in code efficiency.
412 APPENDIX L
~
ABSOLUTE INDIRECT - The second byte of the instruction contains the low
order eight bits of a memory location. The high order eight bits of that
memory location is contained in the third byte of the instruction. The
contents of the fully specified memory location is the low order byte of
the effective address. The next memory location contains the high order
byte of the effective address which is loaded into the sixteen bits of
the program counter.
APPENDIX L 413
~
NOP No Operation
414 APPENDIX L
~
PROGRAMMING MODEL
+---------------+
| A | ACCUMULATOR A
+---------------+
+---------------+
| Y | INDEX REGISTER Y
+---------------+
+---------------+
| X | INDEX REGISTER X
+---------------+
15 7 0
+---------------+---------------+
| PCH | PCL | PROGRAM COUNTER "PC"
+---------------+---------------+
8 7 0
+-+---------------+
|1| S | STACK POINTER "S"
+-+---------------+
7 0
+-+-+-+-+-+-+-+-+
|N|V| |B|D|I|Z|C| PROCESSOR STATUS REG "P"
+-+-+-+-+-+-+-+-+
| | | | | | |
| | | | | | +> CARRY 1=TRUE
| | | | | +--> ZERO 1=RESULT ZERO
| | | | +----> IRQ DISABLE 1=DISABLE
| | | +------> DECIMAL MODE 1=TRUE
| | +--------> BRK COMMAND
| |
| +------------> OVERFLOW 1=TRUE
+--------------> NEGATIVE 1=NEG
APPENDIX L 415
~
INSTRUCTION SET - OP CODES, EXECUTION TIME, MEMORY REQUIREMENTS
+-----------------------------------------------------------------------+
| NOTE: COMMODORE SEMICONDUCTOR GROUP cannot assume liability for the |
| use of undefined OP CODES. |
+-----------------------------------------------------------------------+
416 APPENDIX L
~
APPENDIX L 417
~
+-------------------+
FFFF | |
| ADDRESSABLE |
/ EXTERNAL /
/ MEMORY /
| |
0200 | |
+-------------------+ STACK
01FF | | STACK | | 01FF <--- POINTER
0100 | \|/ Page 1 \|/ | INITIALIZED
+-------------------+
00FF | |
| Page 0 |
+-------------------+
| OUTPUT REGISTER | 0001 <-+- Used For
+-------------------+ | Internal
0000 |DATA DIRECTION REG.| 0000 <-+ I/O Port
+-------------------+
APPLICATIONS NOTES
Locating the Output Register at the internal I/O Port in Page Zero
enhances the powerful Zero Page Addressing instructions of the 6510.
By assigning the I/O Pins as inputs (using the Data Direction Register)
the user has the ability to change the contents of address 0001 (the
Output Register) using peripheral devices. The ability to change these
contents using peripheral inputs, together with Zero Page Indirect
Addressing instructions, allows novel and versatile programming tech-
niques not possible earlier.
+-----------------------------------------------------------------------+
| COMMODORE SEMICONDUCTOR GROUP reserves the right to make changes to |
| any products herein to improve reliability, function or design. |
| COMMODORE SEMICONDUCTOR GROUP does not assume any liability arising |
| out of the application or use of any product or circuit described |
| herein; neither does it convey any license under its patent rights nor|
| the rights of others. |
+-----------------------------------------------------------------------+
418 APPENDIX L
~
APPENDIX M
DESCRIPTION
FEATURES
PIN CONFIGURATION
+----+ +----+
Vss 1 @| +-+ |@ 40 CNT
| |
PA0 2 @| |@ 39 SP
| |
PA1 3 @| |@ 38 RS0
| |
PA2 4 @| |@ 37 RS1
| |
PA3 5 @| |@ 36 RS2
| |
PA4 6 @| |@ 35 RS3
| |
PA5 7 @| |@ 34 /RES
| |
PA6 8 @| |@ 33 D0
| |
PA7 9 @| |@ 32 D1
| |
PB0 10 @| |@ 31 D2
| 6526 |
PB1 11 @| |@ 30 D3
| |
PB2 12 @| |@ 29 D4
| |
PB3 13 @| |@ 28 D5
| |
PB4 14 @| |@ 27 D6
| |
PB5 15 @| |@ 26 D7
| |
PB6 16 @| |@ 25 02
| |
PB7 17 @| |@ 24 /FLAG
| |
/PC 18 @| |@ 23 /CS
| |
TOD 19 @| |@ 22 R/W
| |
Vcc 20 @| |@ 21 /IRQ
+-----------+
420 APPENDIX M
~
APPENDIX M 421
~
MAXIMUM RATINGS
COMMENT
Stresses above those listed under "Absolute Maximum Ratings" may cause
permanent damage to the device. These are stress ratings oily. Functional
operation of this device at these or any other conditions above those
indicated in the operational sections of this specification is not
implied and exposure to absolute maximum rating conditions for extended
periods may affect device reliability.
+-------------------------------+--------+-------+-------+-------+------+
| CHARACTERISTIC | SYMBOL | MIN. | TYP. | MAX. | UNIT |
+-------------------------------+--------+-------+-------+-------+------+
| Input High Voltage | Vih | +2.4 | - | Vcc | V |
+-------------------------------+--------+-------+-------+-------+------+
| Input Low Voltage | Vil | -0.3 | - | - | V |
+-------------------------------+--------+-------+-------+-------+------+
| Input Leakage Current; | Iin | - | 1.0 | 2.5 | uA |
| Vin=Vss+5V | | | | | |
| (TOD, R/W, /FLAG, 02, | | | | | |
| /RES, RS0-RS3, /CS) | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
422 APPENDIX M
~
+-------------------------------+--------+-------+-------+-------+------+
| CHARACTERISTIC | SYMBOL | MIN. | TYP. | MAX. | UNIT |
+-------------------------------+--------+-------+-------+-------+------+
| Port Input Pull-up Resistance | Rpi | 3.1 | 5.0 | - | kohms|
+-------------------------------+--------+-------+-------+-------+------+
| Output Leakage Current for | Itsi | - |+-1.0 |+-10.0 | uA |
| High Impedance State (Three | | | | | |
| State); Vin=4V to 2.4V; | | | | | |
| (D0-D7, SP, CNT, /IRQ) | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
| Output High Voltage | Voh | +2.4 | - | Vcc | V |
| Vcc=MIN, Iload < | | | | | |
| -200uA (PA0-PA7, /PC, | | | | | |
| PB0-PB7, D0-D7) | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
| Output Low Voltage | Vol | - | - | +0.40 | V |
| Vcc=MIN, Iload < 3.2 mA | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
| Output High Current (Sourcing)| Ioh | -200 | -1000 | - | uA |
| Voh > 2.4V (PA0-PA7, | | | | | |
| PB0-PB7, /PC, D0-D7 | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
| Output Low Current (Sinking); | Iol | 3.2 | - | - | mA |
| Vol < .4V (PA0-PA7, /PC, | | | | | |
| PB0-PB7, D0-D7 | | | | | |
+-------------------------------+--------+-------+-------+-------+------+
| Input Capacitance | Cin | - | 7 | 10 | pf |
+-------------------------------+--------+-------+-------+-------+------+
| Output Capacitance | Cout | - | 7 | 10 | pf |
+-------------------------------+--------+-------+-------+-------+------+
| Power Supply Current | Icc | - | 70 | 100 | mA |
+-------------------------------+--------+-------+-------+-------+------+
APPENDIX M 423
~
02-Clock Input
The 02 clock is a TTL compatible input used for internal device opera-
tion and as a timing reference for communicating with the system data
bus.
The /CS input controls the activity of the 6526. A low level on /CS
while 02 is high causes the device to respond to signals on the R/W and
address (RS) lines. A high on /CS prevents these lines from controlling
the 6526. The /CS line is normally activated (low) at 02 by the
appropriate address combination.
R/W-Read/Write Input
RS3-RS0-Address Inputs
The eight data bus pins transfer information between the 6526 and the
system data bus. These pins are high impedance inputs unless CS is low
and R/W and 02 are high to read the device. During this read, the data
bus output buffers are enabled, driving the data from the selected
register onto the system data bus.
426 APPENDIX M
~
/RES-Reset Input
A low on the RES pin resets all internal registers. The port pins are
set as inputs and port registers to zero (although a read of the ports
will return all highs because of passive pullups). The timer control
registers are set to zero and the timer latches to all ones. All other
registers are reset to zero.
APPENDIX M 427
~
+--------+-----------------------+---------------+---------------+------+
| | | 1MHz | 2MHz | |
| | +-------+-------+-------+-------+ |
| Symbol | Characteristic | MIN | MAX | MIN | MAX | Unit |
+--------+-----------------------+-------+-------+-------+-------+------+
| Tacc | Data Access from | | | | | |
| | RS3-RS0 | - | 550 | - | 275 | ns |
| Tco(3) | Data Access from /CS | - | 320 | - | 150 | ns |
| Tdr | Data Release Time | 50 | - | 25 | - | ns |
+--------+-----------------------+-------+-------+-------+-------+------+
+-----------------------------------------------------------------------+
| NOTES: 1 -All timings are referenced from Vil max and Vih min on |
| inputs and Vol max and Voh min on outputs. |
| 2 -Twcs is measured from the later of 02 high or /CS low. /CS |
| must be low at least until the end of 02 high. |
| 3 -Tco is measured from the later of 02 high or /CS low. |
| Valid data is available only after the later of Tacc or Tco. |
+-----------------------------------------------------------------------+
REGISTER MAP
+---+---+---+---+---+----------+----------------------------------------+
|RS3|RS2|RS1|RS0|REG| NAME | |
+---+---+---+---+---+----------+----------------------------------------+
| 0 | 0 | 0 | 0 | 0 | PRA | PERIPHERAL DATA REG A |
| 0 | 0 | 0 | 1 | 1 | PRB | PERIPHERAL DATA REG B |
| 0 | 0 | 1 | 0 | 2 | DDRA | DATA DIRECTION REG A |
| 0 | 0 | 1 | 1 | 3 | DDRB | DATA DIRECTION REG B |
| 0 | 1 | 0 | 0 | 4 | TA LO | TIMER A LOW REGISTER |
| 0 | 1 | 0 | 1 | 5 | TA HI | TIMER A HIGH REGISTER |
| 0 | 1 | 1 | 0 | 6 | TB LO | TIMER B LOW REGISTER |
| 0 | 1 | 1 | 1 | 7 | TB HI | TIMER B HIGH REGISTER |
| 1 | 0 | 0 | 0 | 8 | TOD 10THS| 10THS OF SECONDS REGISTER |
| 1 | 0 | 0 | 1 | 9 | TOD SEC | SECONDS REGISTER |
| 1 | 0 | 1 | 0 | A | TOD MIN | MINUTES REGISTER |
| 1 | 0 | 1 | 1 | B | TOD HR | HOURS-AM/PM REGISTER |
| 1 | 1 | 0 | 0 | C | SDR | SERIAL DATA REGISTER |
| 1 | 1 | 0 | 1 | 0 | ICR | INTERRUPT CONTROL REGISTER |
| 1 | 1 | 1 | 0 | E | CRA | CONTROL REG A |
| 1 | 1 | 1 | 1 | F | CRB | CONTROL REG B |
+---+---+---+---+---+----------+----------------------------------------+
428 APPENDIX M
~
Handshaking
APPENDIX M 429
~
waveforms. Utilizing the CNT input, the timers can count external pulses
or measure frequency, pulse width and delay times of external signals.
Each timer has an associated control register, providing independent
control of the following functions:
Start/Stop
PB On/Off:
A control bit allows the timer output to appear on a PORT B output line
(PB6 for TIMER A and PB7 for TIMER B). This function overrides the DDRB
control bit and forces the appropriate PB line to an output.
Toggle/Pulse
One-Shot/Continuous
A control bit selects either timer mode. In one-shot mode, the timer
will count down from the latched value to zero, generate an interrupt,
reload the latched value, then stop. In continuous mode, the timer will
count from the latched value to zero, generate' an interrupt, reload the
latched value and repeat the procedure continuously.
Force Load
A strobe bit allows the timer latch to be loaded into the timer counter
at any time, whether the timer is running or not.
Input Mode:
Control bits allow selection of the clock used to decrement the timer.
TIMER A can count 02 clock pulses or external pulses applied to the CNT
pin. TIMER B can count (02 pulses, external CNT pulses, TIMER A underflow
pulses or TIMER A underflow pulses while the CNT pin is held high.
430 APPENDIX M
~
The timer latch is loaded into the timer on any timer underflow, on a
force load or following a write to the high byte of the prescaler while
the timer is stopped. If the timer is running, a write to the high byte
will load the timer latch, but not reload the counter.
READ (TIMER)
REG NAME
+-----+---------+------+------+------+------+------+------+------+------+
| 4 | TA LO | TAL7 | TAL6 | TAL5 | TAL4 | TAL3 | TAL2 | TAL1 | TAL0 |
| 5 | TA HI | TAH7 | TAH6 | TAH5 | TAH4 | TAH3 | TAH2 | TAH1 | TAH0 |
| 6 | TB LO | TBL7 | TBL6 | TBL5 | TBL4 | TBL3 | TBL2 | TBL1 | TBL0 |
| 7 | TB HI | TBH7 | TBH6 | TBH5 | TBH4 | TBH3 | TBH2 | TBH1 | TBH0 |
+-----+---------+------+------+------+------+------+------+------+------+
WRITE (PRESCALER)
REG NAME
+-----+---------+------+------+------+------+------+------+------+------+
| 4 | TA LO | PAL7 | PAL6 | PAL5 | PAL4 | PAL3 | PAL2 | PAL1 | PAL0 |
| 5 | TA HI | PAH7 | PAH6 | PAH5 | PAH4 | PAH3 | PAH2 | PAH1 | PAH0 |
| 6 | TB LO | PBL7 | PBL6 | PBL5 | PBL4 | PBL3 | PBL2 | PBL1 | PBL0 |
| 7 | TB HI | PBH7 | PBH6 | PBH5 | PBH4 | PBH3 | PBH2 | PBH1 | PBH0 |
+-----+---------+------+------+------+------+------+------+------+------+
APPENDIX M 431
~
READ
REG NAME
+-----+---------+------+------+------+------+------+------+------+------+
| 8 |TOD 10THS| 0 | 0 | 0 | 0 | T8 | T4 | T2 | T1 |
| 9 |TOD SEC | 0 | SH4 | SH2 | SH1 | SL8 | SL4 | SL2 | SL1 |
| A |TOD MIN | 0 | MH4 | MH2 | MH1 | ML8 | ML4 | ML2 | ML1 |
| B |TOD HR | PM | 0 | 0 | HH | HL8 | HL4 | HL2 | HL1 |
+-----+---------+------+------+------+------+------+------+------+------+
WRITE
CRB7=0 TOD
CRB7=1 ALARM
(SAME FORMAT AS READ)
432 APPENDIX M
~
REG NAME
+-----+---------+------+------+------+------+------+------+------+------+
| C | SDR | S7 | S6 | S5 | S4 | S3 | S2 | S1 | S0 |
+-----+---------+------+------+------+------+------+------+------+------+
There are five sources of interrupts on the 6526: underflow from TIMER
A, underflow from TIMER B, TOD ALARM, Serial Port full/empty and /FLAG.
A single register provides masking and interrupt information. The
interrupt Control Register consists of a write-only MASK register and a
read-only DATA register. Any interrupt will set the corresponding bit in
the DATA register. Any interrupt which is enabled by the MASK register
will set the IR bit (MSB) of the DATA register and bring the /IRQ pin
low. In a multi-chip system, the IR bit can be polled to detect which
chip has generated an interrupt request. The interrupt DATA register is
cleared and the /IRQ line returns high following a read of the DATA
register. Since each interrupt sets an interrupt bit regardless of the
MASK, and each interrupt bit can be selectively masked to prevent the
generation of a processor interrupt, it is possible to intermix polled
interrupts with true interrupts. However, polling the IR bit will cause
the DATA register to clear, therefore, it is up to the user to preserve
the information contained in the DATA register if any polled interrupts
were present.
The MASK register provides convenient control of individual mask bits.
When writing to the MASK register, if bit 7 (SET/CLEAR) of the data
APPENDIX M 433
~
written is a ZERO, any mask bit written with a one will be cleared, while
those mask bits written with a zero will be unaffected. If bit 7 of the
data written is a ONE, any mask bit written with a one will be set, while
those mask bits written with a zero will be unaffected. In order for an
interrupt flag to set IR and generate an Interrupt Request, the corre-
sponding MASK bit must be set.
CONTROL REGISTERS
There are two control registers in the 6526, CRA and CRB. CRA is
associated with TIMER A and CRB is associated with TIMER B. The register
format is as follows:
CRA:
Bit Name Function
0 START 1=START TIMER A, 0=STOP TIMER A. This bit is automatically
reset when underflow occurs during one-shot mode.
1 PBON 1=TIMER A output appears on PB6, 0=PB6 normal operation.
434 APPENDIX M
~
CRB:
Bit Name Function
(Bits CRB0-CRB4 are identical to CRA0-CRA4 for TIMER B with
the exception that bit 1 controls the output of TIMER B on
PB7).
5,6 INMODE Bits CRB5 and CRB6 select one of four input modes for
TIMER B as:
CRB6 CRB5
0 0 TIMER B counts 02 pulses.
0 1 TIMER B counts positive CNT transistions.
1 0 TIMER B counts TIMER A underflow pulses.
1 1 TIMER B counts TIMER A underflow pulses
while CNT is high.
7 ALARM 1=writing to TOD registers sets ALARM, 0=writing to TOD
registers sets TOD clock.
REGNAME TODIN SP MODE IN MODE LOAD RUN MODE OUT MODE PB ON START
+-+---+------+-------+-------+--------+-------+--------+--------+-------+
|E|CRA|0=60Hz|0=INPUT| 0=02 |1=FORCE |0=CONT.|0=PULSE |0=PB6OFF|0=STOP |
| | | | | | LOAD | | | | |
| | |1=50Hz|1=OUTP.| 1=CNT |(STROBE)|1=O.S. |1=TOGGLE|1=PB6ON |1=START|
+-+---+------+-------+-------+--------+-------+--------+--------+-------+
+------------------ TA ----------------------------+
All unused register bits are unaffected by a write and are forced to zero
on a read.
+-----------------------------------------------------------------------+
| COMMODORE SEMICONDUCTOR GROUP reserves the right to make changes to |
| any products herein to improve reliability, function or design. |
| COMMODORE SEMICONDUCTOR GROUP does not assume any liability arising |
| out of the application or use of any product or circuit described |
| herein; neither does it convey any license under its patent rights nor|
| the rights of others. |
+-----------------------------------------------------------------------+
APPENDIX M 435
~
APPENDIX N
The 6566/6567 are multi-purpose color video controller devices for use
in both computer video terminals and video game applications. Both
devices contain 47 control registers which are accessed via a standard
8-bit microprocessor bus (65XX) and will access up to 16K of memory for
display information. The various operating modes and options within each
mode are described.
A13| A12| A11| A10| A09| A08| A07| A06| A05| A04| A03| A02| A01| A00
------+----+----+----+----+----+----+----+----+----+----+----+----+------
VM13|VM12|VM11|VM10| VC9| VC8| VC7| VC6| VC5| VC4| VC3| VC2| VC1| VC0
436 APPENDIX N
~
The eight-bit character pointer permits up to 256 different character
definitions to be available simultaneously. Each character is an 8*8 dot
matrix stored in the character base as eight consecutive bytes. The loca-
tion of the character base is defined by CB13-CB11 also in register 24
($18) which are used for the 3 most significant bits (MSB) of the char-
acter base address. The 11 lower order addresses are formed by the 8-bit
character pointer from the video matrix (D7-D0) which selects a
particular character, and a 3-bit raster counter (RC2-RC0) which selects
one of the eight character bytes. The resulting characters are formatted
as 25 rows of 40 characters each. In addition to the 8-bit character
pointer, a 4-bit COLOR NYBBLE is associated with each video matrix
location (the video matrix memory must be 12 bits wide) which defines one
of sixteen colors for each character.
A13| A12| A11| A10| A09| A08| A07| A06| A05| A04| A03| A02| A01| A00
------+----+----+----+----+----+----+----+----+----+----+----+----+------
CB13|CB12|CB11| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | RC2| RC1| RC0
| CHARACTER |
FUNCTION | BIT | COLOR DISPLAYED
--------------+-----------+----------------------------------------------
Background | 0 | Background #0 color
| | (register 33 ($21)
Foreground | 1 | Color selected by 4-bit color nybble
APPENDIX N 437
~
| CHARACTER |
FUNCTION | BIT PAIR | COLOR DISPLAYED
--------------+------------+---------------------------------------------
Background | 00 | Background #0 Color
| | (register 33 ($21))
Background | 01 | Background #1 Color
| | (register 34 ($22)
Foreground | 10 | Background #2 Color
| | (register 35 ($23)
Foreground | 11 | Color specified by 3 LSB
| | of color nybble
Since two bits are required to specify one dot color, the character is
now displayed as a 4*8 matrix with each dot twice the horizontal size as
in standard mode. Note, however, that each character region can now
contain 4 different colors, two as foreground and two as background (see
MOB priority).
438 APPENDIX N
~
data bit), but the 2 MSB of the character pointer are used to select the
background color for each character region as follows:
CHAR. POINTER |
MS BIT PAIR | BACKGROUND COLOR DISPLAYED FOR 0 BIT
--------------------+----------------------------------------------------
00 | Background #0 color (register 33 ($21))
01 | Background #l color (register 34 ($22))
10 | Background #2 color (register 35 ($23))
11 | Background #3 color (register 36 ($24))
Since the two MSB of the character pointers are used for color informa-
tion, only 64 different character definitions are available. The 6566/
6567 will force CB10 and CB9 to "0" regardless of the original pointer
values, so that only the first 64 character definitions will be accessed.
With extended color mode each character has one of sixteen individually
defined foreground colors and one of the four available background
colors.
+-----------------------------------------------------------------------+
| NOTE: Extended color mode and multi-color mode should not be enabled |
| simultaneously. |
+-----------------------------------------------------------------------+
In bit map mode, the 6566/6567 fetches data from memory in a different
fashion, so that a one-to-one correspondence exists between each
displayed dot and a memory bit. The bit map mode provides a screen
resolution of 320H * 200V individually controlled display dots. Bit map
mode is selected by setting the BMM bit in register 17 ($11) to a "1".
The VIDEO MATRIX is still accessed as in character mode, but the video
matrix data is no longer interpreted as character pointers, but rather as
color data. The VIDEO MATRIX COUNTER is then also used as an address to
fetch the dot data for display from the 8000-byte DISPLAY BASE. The
display base address is formed as follows:
A13| A12| A11| A10| A09| A08| A07| A06| A05| A04| A03| A02| A01| A00
------+----+----+----+----+----+----+----+----+----+----+----+----+------
CB13| VC9| VC8| VC7| VC6| VC5| VC4| VC3| VC2| VC1| VC0| RC2| RC1| RC0
APPENDIX N 439
~
VCx denotes the video matrix counter outputs, RCx denotes the 3-bit
raster line counter and CB13 is from register 24 ($18). The video matrix
counter steps through the same 40 locations for eight raster lines, con-
tinuing to the next 40 locations every eighth line, while the raster
counter increments once for each horizontal video line (raster line).
This addressing results in each eight sequential memory locations being
formatted as an 8*8 dot block on the video display.
When standard bit map mode is in use, the color information is derived
only from the data stored in the video matrix (the color nybble is
disregarded). The 8 bits are divided into two 4-bit nybbles which allow
two colors to be independently selected in each 8*8 dot block. When a bit
in the display memory is a "0" the color of the output dot is set by the
least significant (lower) nybble (LSN). Similarly, a display memory bit
of "1" selects the output color determined by the MSN (upper nybble).
Note that the color nybble (DB11-DB8) IS used for the multi-color bit map
mode. Again, as two bits are used to select one dot color, the horizontal
440 APPENDIX N
~
The movable object block (MOB) is a special type of character which can
be displayed at any one position on the screen without the block
constraints inherent in character and bit map mode. Up to 8 unique MOBs
can be displayed simultaneously, each defined by 63 bytes in memory which
are displayed as a 24*21 dot array (shown below). A number of special
features make MOBs especially suited for video graphics and game
applications.
ENABLE
Each MOB can be selectively enabled for display by setting its corre-
sponding enable bit (MnE) to "1" in register 21 ($15). If the MnE bit is
"0," no MOB operations will occur involving the disabled MOB.
POSlTlON
Each MOB is positioned via its X and Y position register (see register
map) with a resolution of 512 horizontal and 256 vertical positions. The
APPENDIX N 441
~
COLOR
Each MOB has a separate 4-bit register to determine the MOB color. The
two MOB color modes are:
In the standard mode, a "0" bit of MOB data allows any background data
to show through (transparent) and a "1" bit is displayed as the MOB color
determined by the corresponding MOB Color register.
Since two bits of data are required for each color, the resolution of the
MOB is reduced to 12X21, with each horizontal dot expanded to twice
standard size so that the overall MOB size does not change. Note that up
to 3 colors can be displayed in each MOB (in addition to transparent) but
that two of the colors are shared among all the MOBs in the multi-color
mode.
442 APPENDIX N
~
MAGNIFICATION
Each MOB can be selectively expanded (2X) in both the horizontal and
vertical directions. Two registers contain the control bits (MnXE,MnYE)
for the magnification control.
REGISTER | FUNCTION
------------+------------------------------------------------------------
23 ($17) | Horizontal expand MnXE-"1"=expand; "0"=normal
29 ($1D) | Vertical expand MnYE-"1"=expand; "0"=normal
PRIORITY
APPENDIX N 443
~
MOB data bits of "0" ("00" in multi-color mode) are transparent, always
permitting any other information to be displayed.
The MOBs have a fixed priority with respect to each other, with MOB 0
having the highest priority and MOB 7 the lowest. When MOB data (except
transparent data) of two MOBs are coincident, the data from the lower
number MOB will be displayed. MOB vs. MOB data is prioritized before
priority resolution with character or bit map data.
COLLISION DETECTION
444 APPENDIX N
~
The collision interrupt latches are set whenever the first bit of
either register is set to "1". Once any collision bit within a register
is set high, subsequent collisions will not set the interrupt latch
until that collision register has been cleared to all "0s" by a read.
The data for each MOB is Stored in 63 consecutive bytes of memory. Each
block of MOB data is defined by a MOB pointer, located at the end of the
VIDEO MATRIX. Only 1000 bytes of the video matrix are used in the normal
display modes, allowing the video matrix locations 1016-1023 (VM base+
$3F8 to VM base+$3FF) to be used for MOB pointers 0-7, respectively. The
eight-bit MOB pointer from the video matrix together with the six bits
from the MOB byte counter (to address 63 bytes) define the entire 14-bit
address field:
A13| A12| A11| A10| A09| A08| A07| A06| A05| A04| A03| A02| A01| A00
------+----+----+----+----+----+----+----+----+----+----+----+----+------
MP7| MP6| MP5| MP4| MP3| MP2| MP1| MP0| MC5| MC4| MC3| MC2| MC1| MC0
Where MPx are the MOB pointer bits from the video matrix and MCx are the
internally generated MOB counter bits. The MOB pointers are read from the
video matrix at the end of every raster line. When the Y position
register of a MOB matches the current raster line count, the actual
fetches of MOB data begin. Internal counters automatically step through
the 63 bytes of MOB data, displaying three bytes on each raster line.
OTHER FEATURES
SCREEN BLANKING
The display screen may be blanked by setting the DEN bit in register
17 ($11) to a "0". When the screen is blanked, the entire screen will be
filled with the exterior color as set in register 32 ($20). When blanking
is active, only transparent (Phase 1) memory accesses are required, per-
mitting full processor utilization of the system bus. MOB data, however,
will be accessed if the MOBs are not also disabled. The DEN bit must be
set to "1" for normal video display.
APPENDIX N 445
~
ROW/COLUMN SELECT
The RSEL bit is in register 17 ($11) and the CSEL bit is in register 22
($16). For standard display the larger display window is normally used,
while the smaller display window is normally used in conjunction with
scrolling.
SCROLLING
LIGHT PEN
The light pen input latches the current screen position into a pair of
registers (LPX,LPY) on a low-going edge. The X position register 19 ($13)
will contain the 8 MSB of the X position at the time of transition. Since
the X position is defined by a 512-state counter (9 bits) resolution to 2
horizontal dots is provided. Similarly, the Y position is latched to its
446 APPENDIX N
~
register 20 ($14) but here 8 bits provide single raster resolution within
the visible display. The light pen latch may be triggered only once per
frame, and subsequent triggers within the same frame will have no effect.
Therefore, you must take several samples before turning the light pen to
the screen (3 or more samples, average), depending upon the
characteristics of your light pen.
RASTER REGISTER
INTERRUPT REGISTER
LATCH |ENABLE|
BIT | BIT | WHEN SET
-------+------+----------------------------------------------------------
IRST | ERST | Set when (raster count) = (stored raster count)
IMDC | EMDC | Set by MOB-DATA collision register (first collision only)
IMMC | EMMC | Set by MOB-MOB collision register (first collision only)
ILP | ELP | Set by negative transition of LP input (once per frame)
IRQ | | Set high by latch set and enabled (invert of /IRQ output)
APPENDIX N 447
~
RESET
THEORY OF OPERATION
SYSTEM INTERFACE
The 6566/6567 video controller devices interact with the system data
bus in a special way. A 65XX system requires the system buses only during
the Phase 2 (clock high) portion of the cycle. The 6566/6567 devices take
advantage of this feature by normally accessing system memory during the
Phase 1 (clock low) portion of the clock cycle. Therefore, operations
such as character data fetches and memory refresh are totally transparent
to the processor and do not reduce the processor throughput. The video
chips provide the interface control signals required to maintain this bus
sharing.
The video devices provide the signal AEC (address enable control) which
is used to disable the processor address bus drivers allowing the video
device to access the address bus. AEC is active low which, permits direct
connection to the AEC input of the 65XX family. The AEC signal is
448 APPENDIX N
~
The MOB pointers are fetched every other Phase 1 at the end of each
raster line. As required, the additional cycles are used for MOB data
fetches. Again, all necessary bus control is provided by the 6566/6567
devices.
MEMORY INTERFACE
The two versions of the video interface chip, 6566 and 6567, differ in
address output configurations. The 6566 has thirteen fully decoded
APPENDIX N 449
~
addresses for direct connection to the system address bus. The 6567 has
multiplexed addresses for direct connection to 64K dynamic RAMS. The
least significant address bits, A06-A00, are present on A06-A00 while
/RAS is brought low, while the most significant bits, A13-A08, are pres-
ent on A05-A00 while /CAS is brought low. The pins A11-A07 on the 6567
are static address outputs to allow direct connection of these bits to a
conventional 16K (2K*8) ROM. (The lower order addresses require external
latching.)
PROCESSOR INTERFACE
Aside from the special memory accesses described above, the 6566/6567
registers can be accessed similar to any other peripheral device. The
following processor interface signals are provided:
The eight data bus pins are the bidirectional data port, controlled by
/CS, RW, and Phase 0. The data bus can only be accessed while AEC and
Phase 0 are high and /CS is low.
The chip select pin, /CS, is brought low to enable access to the device
registers in conjunction with the address and RW pins. /CS low is recog-
nized only while AEC and Phase 0 are high.
READ/WRITE (R/W)
The lower six address pins, A5-A0, are bidirectional. During a pro-
cessor read or write of the video device, these address pins are inputs.
The data on the address inputs selects the register for read or write as
defined in the register map.
450 APPENDIX N
~
The clock output, Phase 0, is the 1-MHz clock used as the 65XX pro-
cessor Phase 0 in. All system bus activity is referenced to this clock.
The clock frequency is generated by dividing the 8-MHz video input clock
by eight.
INTERRUPTS (/IRQ)
VIDEO INTERFACE
The video output signal from the 6566/6567 consists of two signals
which must be externally mixed together. SYNC/LUM output contains all the
video data, including horizontal and vertical syncs, as well as the
luminance information of the video display. SYNC/LUM is open drain,
requiring an external pull-up of 500 ohms. The COLOR output contains all
the chrominance information, including the color reference burst and the
color of all display data. The COLOR output is open source and should be
terminated with 1000 ohms to ground. After appropriate mixing of these
two signals, the resulting signal can directly drive a video monitor or
be fed to a modulator for use with a standard television.
APPENDIX N 451
~
PIN CONFIGURATION
+----+ +----+
D6 1 @| +-+ |@ 40 Vcc
| |
D5 2 @| |@ 39 D7
| |
D4 3 @| |@ 38 D8
| |
D3 4 @| |@ 37 D9
| |
D2 5 @| |@ 36 D10
| |
D1 6 @| |@ 35 D11
| |
D0 7 @| |@ 34 A10
| |
/IRQ 8 @| |@ 33 A9
| |
LP 9 @| |@ 32 A8
| |
/CS 10 @| |@ 31 A7
| 6567 |
R/W 11 @| |@ 30 A6("1")
| |
BA 12 @| |@ 29 A5(A13)
| |
Vdd 13 @| |@ 28 A4(A12)
| |
COLOR 14 @| |@ 27 A3(A11)
| |
S/LUM 15 @| |@ 26 A2(A10)
| |
AEC 16 @| |@ 25 A1(A9)
| |
PH0 17 @| |@ 24 A0(A8)
| |
/RAS 18 @| |@ 23 A11
| |
/CAS 19 @| |@ 22 PHIN
| |
Vss 20 @| |@ 21 PHCL
+-----------+
452 APPENDIX N (Multiplexed addresses in parentheses)
~
PIN CONFIGURATION
+----+ +----+
D6 1 @| +-+ |@ 40 Vcc
| |
D5 2 @| |@ 39 D7
| |
D4 3 @| |@ 38 D8
| |
D3 4 @| |@ 37 D9
| |
D2 5 @| |@ 36 D10
| |
D1 6 @| |@ 35 D11
| |
D0 7 @| |@ 34 A13
| |
/IRQ 8 @| |@ 33 A12
| |
LP 9 @| |@ 32 A11
| |
/CS 10 @| |@ 31 A10
| 6567 |
R/W 11 @| |@ 30 A9
| |
BA 12 @| |@ 29 A8
| |
Vdd 13 @| |@ 28 A7
| |
COLOR 14 @| |@ 27 A6
| |
S/LUM 15 @| |@ 26 A5
| |
AEC 16 @| |@ 25 A4
| |
PH0 17 @| |@ 24 A3
| |
PHIN 18 @| |@ 23 A2
| |
PHCOL 19 @| |@ 22 A1
| |
Vss 20 @| |@ 21 A0
+-----------+
APPENDIX N 453
~
REGISTER MAP
+----------+------------------------------------------------------------+
| ADDRESS | DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DESCRIPTION |
+----------+------------------------------------------------------------+
| 00 ($00) | M0X7 M0X6 M0X5 M0X4 M0X3 M0X2 M0X1 M0X0 MOB 0 X-position |
| 01 ($01) | M0Y7 M0Y6 M0Y5 M0Y4 M0Y3 M0Y2 M0Y1 M0Y0 MOB 0 Y-position |
| 02 ($02) | M1X7 M1X6 M1X5 M1X4 M1X3 M1X2 M1Xl M1X0 MOB 1 X-position |
| 03 ($03) | M1Y7 M1Y6 M1Y5 M1Y4 M1Y3 M1Y2 M1Y1 M1Y0 MOB 1 Y-position |
| 04 ($04) | M2X7 M2X6 M2X5 M2X4 M2X3 M2X2 M2X1 M2X0 MOB 2 X-position |
| 05 ($05) | M2Y7 M2Y6 M2Y5 M2Y4 M2Y3 M2Y2 M2Y1 M2Y0 MOB 2 Y-position |
| 06 ($06) | M3X7 M3X6 M3X5 M3X4 M3X3 M3X2 M3X1 M3X0 MOB 3 X-position |
| 07 ($07) | M3Y7 M3Y6 M3Y5 M3Y4 M3Y3 M3Y2 M3Y1 M3Y0 MOB 3 Y-position |
| 08 ($08) | M4X7 M4X6 M4X5 M4X4 M4X3 M4X2 M4X1 M4X0 MOB 4 X-position |
| 09 ($09) | M4Y7 M4Y6 M4Y5 M4Y4 M4Y3 M4Y2 M4Y1 M4Y0 MOB 4 Y-position |
| 10 ($0A) | M5X7 M5X6 M5X5 M5X4 M5X3 M5X2 M5X1 M5X0 MOB 5 X-position |
| 11 ($0B) | M5Y7 M5Y6 M5Y5 M5Y4 M5Y3 M5Y2 M5Y1 M5Y0 MOB 5 Y-position |
| 12 ($0C) | M6X7 M6X6 M6X5 M6X4 M6X3 M6X2 M6X1 M6X0 MOB 6 X-position |
| 13 ($0D) | M6Y7 M6Y6 M6Y5 M6Y4 M6Y3 M6Y2 M6Y1 M6Y0 MOB 6 Y-position |
| 14 ($0E) | M7X7 M7X6 M7X5 M7X4 M7X3 M7X2 M7Xl M7X0 MOB 7 X-position |
| 15 ($0F) | M7Y7 M7Y6 M7Y5 M7Y4 M7Y3 M7Y2 M7Y1 M6Y0 MOB 7 Y-position |
| 16 ($10) | M7X8 M6X8 M5X8 M4X8 M3X8 M2X8 M1X8 M0X8 MSB of X-position |
| 17 ($11) | RC8 ECM BMM DEN RSEL Y2 Y1 Y0 See text |
| 18 ($12) | RC7 RC6 RC5 RC4 RC3 RC2 RC1 RC0 Raster register |
| 19 ($13) | LPX8 LPX7 LPX6 LPX5 LPX4 LPX3 LPX2 LPX1 Light Pen X |
| 20 ($14) | LPY7 LPY6 LPY5 LPY4 LPY3 LPY2 LPY1 LPY0 Light Pen Y |
| 21 ($15) | M7E M6E M5E M4E M3E M2E M1E M0E MOB Enable |
| 22 ($16) | - - RES MCM CSEL X2 X1 X0 See text |
| 23 ($17) | M7YE M6YE M5YE M4YE M3YE M2YE M1YE M0YE MOB Y-expand |
454 APPENDIX N
~
| 24 ($18) | VM13 VM12 VM11 VM10 CB13 CB12 CB11 - Memory Pointers |
| 25 ($19) | IRQ - - - ILP IMMC IMBC IRST Interrupt Register|
| 26 ($1A) | - - - - ELP EMMC EMBC ERST Enable Interrupt |
| 27 ($1B) | M7DP M6DP M5DP M4DP M3DP M2DP M1DP M0DP MOB-DATA Priority |
| 28 ($1C) | M7MC M6MC M5MC M4MC M3MC M2MC M1MC M0MC MOB Multicolor Sel|
| 29 ($1D) | M7XE M6XE M5XE M4XE M3XE M2XE M1XE M0XE MOB X-expand |
| 30 ($1E) | M7M M6M M5M M4M M3M M2M M1M M0M MOB-MOB Collision |
| 31 ($1F) | M7D M6D M5D M4D M3D M2D M1D M0D MOB-DATA Collision|
| 32 ($20) | - - - - EC3 EC2 EC1 EC0 Exterior Color |
| 33 ($21) | - - - - B0C3 B0C2 B0C1 B0C0 Bkgd #0 Color |
| 34 ($22) | - - - - B1C3 B1C2 B1C1 B1C0 Bkgd #1 Color |
| 35 ($23) | - - - - B2C3 B2C2 B2C1 B2C0 Bkgd #2 Color |
| 36 ($24) | - - - - B3C3 B3C2 B3C1 B3C0 Bkgd #3 Color |
| 37 ($25) | - - - - MM03 MM02 MM01 MM00 MOB Multicolor #0 |
| 38 ($26) | - - - - MM13 MM12 MM11 MM10 MOB Multicolor #1 |
| 39 ($27) | - - - - M0C3 M0C2 M0C1 M0C0 MOB 0 Color |
| 40 ($28) | - - - - M1C3 M1C2 M1C1 M1C0 MOB 1 Color |
| 41 ($29) | - - - - M2C3 M2C2 M2C1 M2C0 MOB 2 Color |
| 42 ($2A) | - - - - M3C3 M3C2 M3C1 M3C0 MOB 3 Color |
| 43 ($2B) | - - - - M4C3 M4C2 M4C1 M4C0 MOB 4 Color |
| 44 ($2C) | - - - - M5C3 M5C2 M5C1 M5C0 MOB 5 Color |
| 45 ($2D) | - - - - M6C3 M6C2 M6C1 M6C0 MOB 6 Color |
| 46 ($2E) | - - - - M7C3 M7C2 M7C1 M7C0 MOB 7 Color |
+----------+------------------------------------------------------------+
+-----------------------------------------------------------------------+
| NOTE: A dash indicates a no connect. All no connects are read as a |
| "1" |
+-----------------------------------------------------------------------+
APPENDIX N 455
~
COLOR CODES
+--------+--------+--------+--------+--------+--------+-----------------+
| D3 | D2 | D1 | D0 | HEX | DEC | COLOR |
+--------+--------+--------+--------+--------+--------+-----------------+
| 0 | 0 | 0 | 0 | 0 | 0 | BLACK |
| 0 | 0 | 0 | 1 | 1 | 1 | WHITE |
| 0 | 0 | 1 | 0 | 2 | 2 | RED |
| 0 | 0 | 1 | 1 | 3 | 3 | CYAN |
| 0 | 1 | 0 | 0 | 4 | 4 | PURPLE |
| 0 | 1 | 0 | 1 | 5 | 5 | GREEN |
| 0 | 1 | 1 | 0 | 6 | 6 | BLUE |
| 0 | 1 | 1 | 1 | 7 | 7 | YELLOW |
| 1 | 0 | 0 | 0 | 8 | 8 | ORANGE |
| 1 | 0 | 0 | 1 | 9 | 9 | BROWN |
| 1 | 0 | 1 | 0 | A | 10 | LT RED |
| 1 | 0 | 1 | 1 | B | 11 | DARK GREY |
| 1 | 1 | 0 | 0 | C | 12 | MED GREY |
| 1 | 1 | 0 | 1 | 0 | 13 | LT GREEN |
| 1 | 1 | 1 | 0 | E | 14 | LT BLUE |
| 1 | 1 | 1 | 1 | F | 15 | LT GREY |
+--------+--------+--------+--------+--------+--------+-----------------+
456 APPENDIX N
~
APPENDIX O
CONCEPT
FEATURES
o 3 TONE OSCILLATORS
Range: 0-4 kHz
o 4 WAVEFORMS PER OSCILLATOR
Triangle, Sawtooth,
Variable Pulse, Noise
o 3 AMPLITUDE MODULATORS
Range: 48 dB
o 3 ENVELOPE GENERATORS
Exponential response
Attack Rate: 2 ms-8 s
Decay Rate: 6 ms-24 s
Sustain Level: 0-peak volume
Release Rate: 6 ms-24 s
o OSCILLATOR SYNCHRONIZATION
o RING MODULATION
o PROGRAMMABLE FILTER
Cutoff range: 30 Hz-12 kHz
12 dB/octave Rolloff
Low pass, Bandpass,
High pass, Notch outputs
Variable Resonance
APPENDIX O 457
~
o MASTER VOLUME CONTROL
o 2 A/D POT INTERFACES
o RANDOM NUMBER/MODULATION GENERATOR
o EXTERNAL AUDIO INPUT
PIN CONFIGURATION
+----+ +----+
CAP1A 1 @| +-+ |@ 28 Vdd
| |
CAP1B 2 @| |@ 27 AUDIO OUT
| |
CAP2A 3 @| |@ 26 EXT IN
| |
CAP2B 4 @| |@ 25 Vcc
| |
/RES 5 @| |@ 24 POT X
| |
02 6 @| |@ 23 POT Y
| |
R/W 7 @| |@ 22 D7
| 6581 |
/CS 8 @| SID |@ 21 D6
| |
A0 9 @| |@ 20 D5
| |
A1 10 @| |@ 19 D4
| |
A2 11 @| |@ 18 D3
| |
A3 12 @| |@ 17 D2
| |
A4 13 @| |@ 16 D1
| |
GND 14 @| |@ 15 D0
+-----------+
458 APPENDIX O
~
[THE PICTURE IS MISSING!]
APPENDIX O 459
~
DESCRIPTION
460 APPENDIX O
~
Voice 2
7 07 F7 F6 F5 F4 F3 F2 F1 F0 FREQ LO WO
8 08 F15 F14 F13 F12 F11 F10 F9 F8 FREQ HI WO
9 09 PW7 PW6 PW5 PW4 PW3 PW2 PW1 PW0 PW LO WO
10 0A - - - - PW11 PW10 PW9 PW8 PW HI WO
11 0B NOISE PULSE SAW TRIANG TEST RING SYNC GATE CONTROL REG WO
12 0C ATK3 ATK2 ATK1 ATK0 DCY3 DCY2 DCY1 DCY0 ATTACK/DECAY WO
13 0D STN3 STN2 STN1 STN0 RLS3 RLS2 RLS1 RLS0 SUSTAIN/RELEASE WO
Voice 3
14 0E F7 F6 F5 F4 F3 F2 F2 F1 FREQ LO WO
15 0F F15 F14 F13 F12 F11 F10 F9 F8 FREQ HI WO
16 10 PW7 PW6 PW5 PW4 PW3 PW2 PW1 PW0 PW LO WO
17 11 - - - - PW11 PW10 PW9 PW8 PW HI WO
18 12 NOISE PULSE SAW TRIANG TEST RING SYNC GATE CONTROL REG WO
19 13 ATK3 ATK2 ATK1 ATK0 DCY3 DCY2 DCY1 DCY0 ATTACK/DECAY WO
20 14 STN3 STN2 STN1 STN0 RLS3 RLS2 RLS1 RLS0 SUSTAIN/RELEASE WO
Filter
21 15 - - - - - FC2 FC1 FC0 FC LO WO
22 16 FC10 FC9 FC8 FC7 FC6 FC5 FC4 FC3 FC HI WO
23 17 RES3 RES2 RES1 RES0 FILTEX FILT3 FILT2 FILT1 RES/FILT WO
24 18 3OFF HP BP LP VOL3 VOL2 VOL1 VOL0 MODE/VOL WO
Misc.
25 19 PX7 PX6 PX5 PX4 PX3 PX2 PX1 PX0 POT X RO
26 1A PY7 PY6 PY5 PY4 PY3 PY2 PY1 PY0 POT Y RO
27 1B O7 O6 O5 O4 O3 O2 O1 O0 OSC3/RANDOM RO
28 1C E7 E6 E5 E4 E3 E2 E1 E0 ENV3 RO
APPENDIX O 461
~
VOICE 1
Fout = (Fn*Fclk/16777216) Hz
Fout = (Fn*0.059604645) Hz
PWout = (PWn/40.95) %
This register contains eight control bits which select various options
on Oscillator 1.
GATE (Bit 0): The GATE bit controls the Envelope Generator for Voice 1.
When this bit is set to a one, the Envelope Generator is Gated
(triggered) and the ATTACK/DECAY/SUSTAIN cycle is initiated. When the bit
is reset to a zero, the RELEASE cycle begins. The Envelope Generator
controls the amplitude of Oscillator I appearing at the audio output,
therefore, the GATE bit must be set (along with suitable envelope pa-
rameters) for the selected output of Oscillator 1 to be audible. A de-
tailed discussion of the Envelope Generator can be found at the end of
this Appendix.
SYNC (Bit 1): The SYNC bit, when set to a one, synchronizes the
fundamental frequency of Oscillator 1 with the fundamental frequency of
Oscillator 3, producing "Hard Sync" effects.
Varying the frequency of Oscillator 1 with respect to Oscillator 3 pro-
duces a wide range of complex harmonic structures from Voice I at the
frequency of Oscillator 3. In order for sync to occur, Oscillator 3 must
be set to some frequency other than zero but preferably lower than the
frequency of Oscillator 1. No other parameters of Voice 3 have any effect
on sync.
RING MOD (Bit 2): The RING MOD bit, when set to a one, replaces the
Triangle waveform output of Oscillator 1 with a "Ring Modulated"
combination of Oscillators 1 and 3. Varying the frequency of Oscillator 1
with respect to Oscillator 3 produces a wide range of non-harmonic
overtone structures for creating bell or gong sounds and for special ef-
fects. In order for ring modulation to be audible, the Triangle waveform
of Oscillator 1 must be selected and Oscillator 3 must be set to some
frequency other than zero. No other parameters of Voice 3 have any effect
on ring modulation.
TEST (Bit 3): The TEST bit, when set to a one, resets and locks Oscil-
lator 1 at zero until the TEST bit is cleared. The Noise waveform output
of Oscillator 1 is also reset and the Pulse waveform output is held at a
DC level. Normally this bit is used for testing purposes, however, it can
be used to synchronize Oscillator 1 to external events, allowing the
generation of highly complex waveforms under real-time software control.
APPENDIX O 463
~
(Bit 4): When set to a one, the Triangle waveform output of Oscillator
1 is selected. The Triangle waveform is low in harmonics and has a
mellow, flute-like quality.
(Bit 5): When set to a one, the Sawtooth waveform output of Oscillator
1 is selected. The Sawtooth waveform is rich in even and odd harmonics
and has a bright, brassy quality.
(Bit 6): When set to a one, the Pulse waveform output of Oscillator 1
is selected. The harmonic content of this waveform can be adjusted by the
Pulse Width registers, producing tone qualities ranging from a bright,
hollow square wave to a nasal, reedy pulse. Sweeping the pulse width in
real-time produces a dynamic "phasing" effect which adds a sense of
motion to the sound. Rapidly jumping between different pulse widths can
produce interesting harmonic sequences.
NOISE (Bit 7): When set to a one, the Noise output waveform of
Oscillator 1 is selected. This output is a random signal which changes at
the frequency of Oscillator 1. The sound quality can be varied from a low
rumbling to hissing white noise via the Oscillator 1 Frequency registers.
Noise is useful in creating explosions, gunshots, jet engines, wind, surf
and other unpitched sounds, as well as snore drums and cymbals. Sweeping
the oscillator frequency with Noise selected produces a dramatic rushing
effect.
One of the output waveforms must be selected for Oscillator 1 to be
audible, however, it is NOT necessary to de-select waveforms to silence
the output of Voice 1. The amplitude of Voice 1 at the final output is a
function of the Envelope Generator only.
+-----------------------------------------------------------------------+
| NOTE: The oscillator output waveforms are NOT additive. If more than |
| one output waveform is selected simultaneously, the result will be a |
| logical ANDing of the waveforms. Although this technique can be used |
| to generate additional waveforms beyond the four listed above, it must|
| be used with care. If any other waveform is selected while Noise is |
| on, the Noise output can "lock up " If this occurs, the Noise output |
| will remain silent until reset by the TEST bit or by bringing RES |
| (pin 5) low. |
+-----------------------------------------------------------------------+
464 APPENDIX O
~
+-----------------------------------------------------------------------+
| NOTE: The cycling of the Envelope Generator can be altered at any |
| point via the Gate bit. The Envelope Generator can be Gated and |
| Released without restriction. For example, if the Gate bit is reset |
| before the envelope has finished the ATTACK cycle, the RELEASE cycle |
| will immediately begin, starting from whatever amplitude had been |
| reached. if the envelope is then Gated again (before the RELEASE cycle|
| has reached zero amplitude), another ATTACK cycle will begin, starting|
| from whatever amplitude had been reached. This technique can be used |
| to generate complex amplitude envelopes via real-time software |
| control. |
+-----------------------------------------------------------------------+
APPENDIX O 465
~
+-----------------------------------------------------------------------+
| NOTE: Envelope rates are based on a 1.0-MHz 02 clock. For other 02 |
| frequencies, multiply the given rate by 1 MHz/02. The rates refer to |
| the amount of time per cycle. For example, given an ATTACK value of 2,|
| the ATTACK cycle would take 16 ms to rise from zero to peak amplitude.|
| The DECAY/RELEASE rates refer to the amount of time these cycles would|
| take to fall from peak amplitude to zero. |
+-----------------------------------------------------------------------+
VOICE 2
466 APPENDIX O
~
VOICE 3
FILTER
APPENDIX O 467
~
Bits 4-7 of this register select various Filter mode and output
options:
LP (Bit 4): When set to a one, the Low-Pass output of the Filter is
selected and sent to the audio output. For a given Filter input signal,
all frequency components below the Filter Cutoff Frequency are passed
unaltered, while all frequency components above the Cutoff are attenuated
at a rate of 12 dB/Octave. The Low-Pass mode produces fullbodied sounds.
BP (Bit 5): Same as bit 4 for the Bandpass output. All frequency
components above and below the Cutoff are attenuated at a rate of 6
dB/Octave. The Bandpass mode produces thin, open sounds.
HP (Bit 6): Same as bit 4 for the High-Pass output. All frequency
components above the Cutoff are passed unaltered, while all frequency
components below the Cutoff are attenuated at a rate of 12 dB/Octave.
The High-Pass mode produces tinny, buzzy sounds.
3 OFF (Bit 7): When set to a one, the output of Voice 3 is disconnected
from the direct audio path. Setting Voice 3 to bypass the Filter
(FILT 3 = 0) and setting 3 OFF to a one prevents Voice 3 from reaching
the audio output. This allows Voice 3 to be used for modulation purposes
without any undesirable output.
+-----------------------------------------------------------------------+
| NOTE: The Filter output modes ARE additive and multiple Filter modes |
| may be selected simultaneously. For example, both LP and HP modes can |
| be selected to produce a Notch (or Band Reject) Filter response. In |
| order for the Filter to have any audible effect, at least one Filter |
| output must be selected and at least one Voice must be routed through |
| the Filter. The Filter is, perhaps, the most important element in SID |
| as it allows the generation of complex tone colors via subtractive |
| synthesis (the Filter is used to eliminate specific frequency |
| components from a harmonically rich input signal). The best results |
| are achieved by varying the Cutoff Frequency in real-time. |
+-----------------------------------------------------------------------+
Bits 0-3 (VOL0-VOL3) select 1 of 16 overall Volume levels for the final
composite audio output. The output volume levels range from no output (0)
to maximum volume (15 or $F) in 16 linear steps. This control can be used
as a static volume control for balancing levels in multi-chip systems or
for creating dynamic volume effects, such as Tremolo. Some Volume level
other than zero must be selected in order for SID to produce any sound.
468 APPENDIX O
~
MISCELLANEOUS
This register allows the microprocessor to read the upper 8 output bits
of Oscillator 3. The character of the numbers generated is directly re-
lated to the waveform selected. If the Sawtooth waveform of Oscillator 3
is selected, this register will present a series of numbers incrementing
from 0 to 255 ($FF) at a rate determined by the frequency of Oscillator
3. If the Triangle waveform is selected, the output will increment from 0
up to 255, then decrement down to 0. If the Pulse waveform is selected,
the output will jump between 0 and 255. Selecting the Noise waveform
will produce a series of random numbers, therefore, this register can be
used as a random number generator for games. There are numerous timing
and sequencing applications for the OSC 3 register, however, the chief
function is probably that of a modulation generator. The numbers
generated by this register can be added, via software, to the Oscillator
or Filter Frequency registers or the Pulse Width registers in real-time.
Many dynamic effects can be generated in this manner. Siren-like sounds
can be created by adding the OSC 3 Sawtooth output to the frequency
control of another oscillator. Synthesizer "Sample and Hold" effects can
be produced by adding the OSC 3 Noise output to the Filter Frequency
control registers. Vibrato can be produced by setting Oscillator 3 to a
frequency around 7 Hz and adding the OSC 3 Triangle output (with proper
scaling) to the Frequency control of another oscillator. An unlimited
range of effects are available by altering the frequency of Oscillator 3
and scaling the OSC 3 output. Normally, when Oscillator 3 is used for
modulation, the audio output of Voice 3 should be eliminated (3 OFF = 1).
APPENDIX O 469
~
Same as OSC 3, but this register allows the microprocessor to read the
output of the Voice 3 Envelope Generator. This output can be added to the
Filter Frequency to produce harmonic envelopes, WAH-WAH, and similar
effects. "Phaser" sounds can be created by adding this output to the
frequency control registers of an oscillator. The Voice 3 Envelope
Generator must be Gated in order to produce any output from this regis-
ter. The OSC 3 register, however, always reflects the changing output of
the oscillator and is not affected in any way by the Envelope Generator.
These pins are used to connect the two integrating capacitors required
by the programmable Filter. C1 connects between pins 1 and 2, C2 between
pins 3 and 4. Both capacitors should be the some value. Normal operation
of the Filter over the audio range (approximately 30 Hz-12 kHz) is
accomplished with a value of 2200 pF for C1 and C2. Polystyrene
capacitors are preferred and in complex polyphonic systems, where many
SID chips must track each other, matched capacitors are recommended.
The frequency range of the Filter can be tailored to specific applica-
tions by the choice of capacitor values. For example, a low-cost game may
not require full high-frequency response. In this case, larger values
for C1 and C2 could be chosen to provide more control over the bass
frequencies of the Filter. The maximum Cutoff Frequency of the Filter is
given by:
FCmax = 2.6E-5/C
Where C is the capacitor value. The range of the Filter extends 9 octaves
below the maximum Cutoff Frequency.
RES (Pin 5)
This TTL-level input is the reset control for SID. When brought low for
at least ten 02 cycles, all internal registers are reset to zero and the
audio output is silenced. This pin is normally connected to the reset
line of the microprocessor or a power-on-clear circuit.
470 APPENDIX O
~
02 (Pin 6)
This TTL-Level input is the master clock for SID. All oscillator
frequencies and envelope rates are referenced to this clock. 02 also
controls data transfers between SID and the microprocessor. Data can only
be transferred when (02 is high. Essentially, (02 acts as a high-active
chip select as far as data transfers are concerned. This pin is normally
connected to the system clock, with a nominal operating frequency of 1.0
MHz.
R/W (Pin 7)
CS (Pin 8)
This TTL-Level input is a low active chip select which controls data
transfers between SID and the microprocessor. CS must be low for any
transfer. A Read from the selected SID register can only occur if CS is
low, 02 is high and R/W is high. A Write to the selected SID register can
only occur if CS is low, (02 is high and R/W is low. This pin is normally
connected to address decoding circuitry, allowing SID to reside in the
memory map of a system.
These TTL-Level inputs are used to select one of the 29 SID registers.
Although enough addresses are provided to select 1 of 32 registers, the
remaining three register locations are not used. A Write to any of these
three locations is ignored and a Read returns invalid data. These pins
are normally connected to the corresponding address lines of the micro-
processor so that SID may be addressed in the same manner as memory.
For best results, the ground line between SID and the power supply
should be separate from ground lines to other digital circuitry. This
will minimize digital noise at the audio output.
APPENDIX O 471
~
These bidirectional lines are used to transfer data between SID and the
microprocessor. They are TTL compatible in the input mode and capable of
driving 2 TTL loads in the output mode. The data buffers are usually in
the high-impedance off state. During a Write operation, the data buffers
remain in the off (input) state and the microprocessor supplies data to
SID over these lines. During a Read operation, the data buffers turn on
and SID supplies data to the microprocessor over these lines. The pins
are normally connected to the corresponding data lines of the micro-
processor.
These pins are inputs to the A/D converters used to digitize the posi-
tion of potentiometers. The conversion process is based on the time con-
stant of a capacitor tied from the POT pin to ground, charged by a
potentiometer tied from the POT pin to +5 volts. The component values are
determined by:
RC = 4.7E-4
As with the GND line, a separate +5 VDC line should be run between SID
Vcc and the power supply in order to minimize noise. A bypass capacitor
should be located close to the pin.
This analog input allows external audio signals to be mixed with the
audio output of SID or processed through the Filter. Typical sources in-
clude voice, guitar, and organ. The input impedance of this pin is on the
order of 100 kohms. Any signal applied directly to the pin should ride at
a DC level of 6 volts and should not exceed 3 volts p-p. In order to pre-
472 APPENDIX O
~
As with Vcc, a separate +12 VDC line should be run to SID VDD and a
bypass capacitor should be used.
+--------------------------+------------+-----------------+-------------+
| RATING | SYMBOL | VALUE | UNITS |
+--------------------------+------------+-----------------+-------------+
| Supply Voltage | VDD | -0.3 to +17 | VDC |
| Supply Voltage | VCC | -0.3 to +7 | VDC |
| Input Voltage (analog) | Vina | -0.3 to +17 | VDC |
| Input Voltage (digital) | Vind | -0.3 to +7 | VDC |
| Operating Temperature | Ta | 0 to +70 | Celsius |
| Storage Temperature | Tstg | -55 to +150 | Celsius |
+--------------------------+------------+-----------------+-------------+
APPENDIX O 473
~
ELECTRICAL CHARACTERISTICS (Vdd=12 VDC+-5%, Vcc=5 VDC+-5%,
Ta=0 to 70 Celsius)
+------------------------------------------+----+-----+---+-------+-----+
| CHARACTERISTIC SYMBOL MIN |TYP| MAX |UNITS|
+------------------------------------------+----+-----+---+-------+-----+
| Input High Voltage (RES, 02, RIN, CS, | Vih| 2 | - | Vcc | VDC |
| Input Low Voltage A0-A4, D0-D7) | Vil|-0.3 | - | 0.8 | VDC |
+------------------------------------------+----+-----+---+-------+-----+
| Input Leakage Current (RES, 02, R/W, CS, | Iin| - | - | 2.5 | uA |
| A0-A4; Vin=0-5 VDC)| | | | | |
| Three-State (Off) (D0-D7; Vcc=max) |Itsi| - | - | 10 | uA |
+------------------------------------------+----+-----+---+-------+-----+
| Input Leakage Current Vin=0.4-2.4 VDC | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Output High Voltage (D0-D7; Vcc=min, | Voh| 2.4 | - |Vcc-0.7| VDC |
| I load=200 uA) | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Output Low Voltage (D0-D7; Vcc=max, | Vol| GND | - | 0.4 | VDC |
| I load=3.2 mA) | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Output High Current (D0-D7; Sourcing, | Ioh| 200 | - | - | uA |
| Voh=2.4 VDC) | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Output Low Current (D0-D7; Sinking, | Iol| 3.2 | - | - | mA |
| Vol=0.4 VDC) | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Input Capacitance (RES, 02, R/W, CS, | Cin| - | - | 10 | pF |
| A0-A4, D0-D7) | | | | | |
+------------------------------------------+----+-----+---+-------+-----+
| Pot Trigger Voltage (POTX, POTY) |Vpot| - Vcc/2 - | VDC |
+------------------------------------------+----+-----+---+-------+-----+
| Pot Sink Current (POTX, POTY) |Ipot| 500 | - | - | uA |
+------------------------------------------+----+-----+---+-------+-----+
| Input Impedance (EXT IN) | Rin| 100 |150| - |kohms|
+------------------------------------------+----+-----+---+-------+-----+
| Audio Input Voltage (EXT IN) | Vin| 5.7 | 6 | 6.3 | VDC |
| | | - |0.5| 3 | VAC |
474 APPENDIX O
~
+------------------------------------------+----+-----+---+-------+-----+
| Audio Output Voltage (AUDIO OUT; 1 kohm | | | | | |
| load, volume=max) |Vout| 5.7 | 6 | 6.3 | VDC |
| One Voice on: | | 0.4 |0.5| 0.6 | VAC |
| All Voices on: | | 1.0 |1.5| 2.0 | VAC |
+------------------------------------------+----+-----+---+-------+-----+
| Power Supply Current (VDD) | Idd| - | 20| 25 | mA |
+------------------------------------------+----+-----+---+-------+-----+
| Power Supply Current (VCC) | Icc| - | 70| 100 | mA |
+------------------------------------------+----+-----+---+-------+-----+
| Power Dissipation (Total) | Pd | - |600| 1000 | mW |
+------------------------------------------+----+-----+---+-------+-----+
APPENDIX O 475
~
+----------+----------------------------+-------+-------+-------+-------+
| SYMBOL | NAME | MIN | TYP | MAX | UNITS |
+----------+----------------------------+-------+-------+-------+-------+
| Tcyc | Clock Cycle Time | 1 | - | 20 | uA |
| Tc | Clock High Pulse Width | 450 | 500 |10,000 | ns |
| Tr,Tf | Clock Rise/Fall Time | - | - | 25 | ns |
| Trs | Read Set-Up Time | 0 | - | - | ns |
| Trh | Read Hold Time | 0 | - | - | ns |
| Tacc | Access Time | - | - | 300 | ns |
| Tah | Address Hold Time | 10 | - | - | ns |
| Tch | Chip Select Hold Time | 0 | - | - | ns |
| Tdh | Data Hold Time | 20 | - | - | ns |
+----------+----------------------------+-------+-------+-------+-------+
476 APPENDIX O
~
WRITE CYCLE
+----------+----------------------------+-------+-------+-------+-------+
| SYMBOL | NAME | MIN | TYP | MAX | UNITS |
+----------+----------------------------+-------+-------+-------+-------+
| Tw | Write Pulse Width | 300 | - | - | ns |
| Twh | Write Hold Time | 0 | - | - | ns |
| Taws | Address Set-up Time | 0 | - | - | ns |
| Tah | Address Hold Time | 10 | - | - | ns |
| Tch | Chip Select Hold Time | 0 | - | - | ns |
| Tvd | Valid Data | 80 | - | - | ns |
| Tdh | Data Hold Time | 10 | - | - | ns |
+----------+----------------------------+-------+-------+-------+-------+
APPENDIX O 477
~
The table in Appendix E lists the numerical values which must be stored
in the SID Oscillator frequency control registers to produce the notes of
the equal-tempered musical scale. The equal-tempered scale consists of an
octave containing 12 semitones (notes): C,D,E,F,G,A,B and C#,D#,F#,G#,A#.
The frequency of each semitone is exactly the 12th root of 2 times the
frequency of the previous semitone. The table is based on a (02 clock of
1.02 MHz. Refer to the equation given in the Register Description for use
of other master clock frequencies. The scale selected is concert pitch,
in which A-4 = 440 Hz. Transpositions of this scale and scales other than
the equal-tempered scale are also possible.
Although the table in Appendix E provides a simple and quick method for
generating the equal-tempered scale, it is very memory inefficient as it
requires 192 bytes for the table alone. Memory efficiency can be improved
by determining the note value algorithmically. Using the fact that each
note in an octave is exactly half the frequency of that note in the next
octave, the note look-up table can be reduced from 96 entries to 12
entries, as there are 12 notes per octave. If the 12 entries (24 bytes)
consist of the 16-bit values for the eighth octave (C-7 through B-7),
then notes in lower octaves can be derived by choosing the appropriate
note in the eighth octave and dividing the 16-bit value by two for each
octave of difference. As division by two is nothing more than a right-
shift of the value, the calculation can easily be accomplished by a
simple software routine. Although note B-7 is beyond the range of the
oscillators, this value should still be included in the table for
calculation purposes (the MSB of B-7 would require a special software
case, such as generating this bit in the CARRY before shifting). Each
note must be specified in a form which indicates which of the 12
semitones is desired, and which of the eight octaves the semitone is in.
Since four bits are necessary to select 1 of 12 semitones and three bits
are necessary to select 1 of 8 octaves, the information can fit in one
byte, with the lower nybble selecting the semitone (by addressing the
look-up table) and the upper nybble being used by the division routine to
determine how many times the table value must be right-shifted.
478 APPENDIX O
~
Note that the tone can be held at the intermediate SUSTAIN level for
as long as desired. The tone will not begin to die away until GATE is
cleared. With minor alterations, this basic envelope can be used for
brass and woodwinds as well as strings.
An entirely different form of envelope is produced by percussion in-
struments such as drums, cymbals and gongs, as well as certain
keyboards such as pianos and harpsichords. The percussion envelope is
characterized by a nearly instantaneous attack, immediately followed by
a decay to zero volume. Percussion instruments cannot be sustained at
APPENDIX O 479
~
ATTACK: 0 2 ms +
DECAY: 9 750 ms |+
SUSTAIN: 0 | +
RELEASE: 9 750 ms ----+ +--
A D
Note that the tone immediately begins to decay to zero amplitude after
the peak is reached, regardless of when GATE is cleared. The amplitude
envelope of pianos and harpsichords is somewhat more complicated, but can
be generated quite easily with the ADSR. These instruments reach full
volume when a key is first struck. The amplitude immediately begins to
die away slowly as long as the key remains depressed. If the key is
released before the sound has fully died away, the amplitude will
immediately drop to zero. This envelope is shown below:
ATTACK: 0 2 ms +
DECAY: 9 750 ms |+
SUSTAIN: 0 | +
RELEASE: 0 6 ms ----+ +-----
A D R
Note that the tone decays slowly until GATE is cleared, at which point
the amplitude drops rapidly to zero.
The most simple envelope is that of the organ, When a key is pressed,
the tone immediately reaches full volume and remains there. When the key
is released, the tone drops immediately to zero volume. This envelope is
shown below:
+----+
ATTACK: 0 2 ms | |
DECAY: 0 6 ms | |
SUSTAIN: 15 ($F) | |
RELEASE: 0 6 ms ----+ +---
A S R
The real power of SID lies in the ability to create original sounds
rather than simulations of acoustic instruments. The ADSR is capable of
creating envelopes which do not correspond to any "real" instruments. A
good example would be the "backwards" envelope. This envelope is
characterized by a slow attack and rapid decay which sounds very much
480 APPENDIX O
~
like an instrument that has been recorded on tape then played backwards.
This envelope is shown below: S
+----------+
ATTACK: 10 ($A) 500 ms A / | R
DECAY: 0 6 ms / +
SUSTAIN: 15 ($F) / +
RELEASE: 3 72 ms --+ +--
APPENDIX O 481
~
APPENDIX P
GLOSSARY
482 APPENDIX P
~
INDEX
INDEX 483
~
484 INDEX
~
INDEX 485
~
Files (cassette), 40, 50, 55, 59-60, 65-66, 75, 84-85, 91, 337-338,
340-342
Files (disk), 40, 50, 55, 59-60, 65-66, 75, 84-85, 91, 337-338, 342
Filtering, 183, 189, 199-202
Fire button, joystick/paddle/lightpen, 328-329, 343-348
FOR statement, 20-21, 32, 39, 47-48, 62-63, 77-78, 86, 110, 155-156,
165-166, 169-171, 198-199, 309, 374
Football, 45
FREE function, 32, 49, 109, 374
FuNction function, 32, 47, 374
Functions, 31-34, 35, 37-38, 42, 46-47, 49, 56-57, 61, 69-70, 79-80,
83-85, 87-90, 374-375
Game controls and ports, 343-348
GET statement, 22-24, 32, 37, 49-50, 93, 374-375
GETIN, 272-273, 283
GET# statement, 32, 37, 50, 55, 65, 341-342, 348, 374
GOSUB statement, 32, 39, 51-52, 77, 79, 85, 374
GOTO (GO TO) statement, 32, 37, 48, 52-53, 64, 77, 81, 86, 374
Graphics keys, xiv-xv, 70-74, 95-96, 108-114
Graphics mode, xiv-xv, 99-183
Graphics mode, bit mapped, 121-130
Graphics symbols, (see graphics keys)
Greater than, equal to or, 3, 12-13, 16
486 INDEX
~
Joysticks, 343-345
JMP, 228-230, 232, 244, 254, 270, 308
JSR, 228-230, 233, 244, 255, 268, 270
INDEX 487
~
488 INDEX
~
POKE statement, 25, 33, 69-70, 94, 101-102, 104, 106, 109-111, 115-116,
118, 120-123, 126-130, 134-137, 150, 153-161, 165-166, 168-170,
172-173, 177-178, 180, 184-186, 194, 198-199, 204-205, 211, 220, 309,
361, 375-376
Ports, I/O, 214, 335-375, 395-397
POSition function, 33, 70, 375
Power/Play, xvi, 390
PRINT statement, 13-15, 18-22, 25, 33-54, 56-61, 63, 68-75, 79-80,
83-84, 87-89, 94-96, 109, 168, 171, 210, 213, 220, 375
PRINT# statement, 33, 40-41, 75-76, 85, 94, 337, 340-341, 348, 353, 375
Printer, xv, 338-339
Program counter, 214
Program mode, 3
Prompt, 45
RAM, 49, 100-101, 104-105, 107-108, 110-111, 117, 122, 260-262, 269, 340
RAMTAS, 273, 291
Random numbers, 53, 80
RaNDom function, 33, 43, 53, 80, 375
Raster interrupt, 131, 150-152
RDTIM, 273, 291
READST, 273, 292
READ statement, 33, 42, 76-77, 111, 170, 309,375
Release, (see A/D/S/R)
Register map, CIA chip, 428
Register map, SID chip, 461
Register map, VIC chip, 454-455
REMark statement, 25-26, 33, 37-38, 41-42, 45-46, 50, 77-78, 93-95, 101,
118, 198-199, 338, 340, 356, 375
Reserved words, (see Keywords, BASIC)
RESTOR, 273, 293
RESTORE key, 22, 92, 126, 353
RESTORE statement, 33, 78, 375
RETURN key, 3, 18, 22, 41, 50-51, 74, 93-97, 154-155, 166, 217, 220,
336-337, 370
RETURN statement, 33, 51-52, 79, 85, 175, 375
ReVerSe ON, OFF keys, 97
RIGHT$ function, 33, 79, 375
ROL, 233, 248, 255
ROM, 261, 268-269
INDEX 489
~
490 INDEX
~
INDEX 491
~
SIMPLE VARIABLES
Real XY +-1.70141183E+38
+-2.93873588E-39
Integer XY% +-32767
String XY$ 0 to 255 characters
ARRAY VARIABLES
Type Name
Single Dimension XY(5)
Two-Dimension XY(5,5)
Three-Dimension XY(5,5,5)
SYSTEM COMMANDS
~
ARRAYS AND STRINGS
INPUT/OUTPUT COMMANDS
----------------------------------------------------------
C= COMMODORE
COMPUTER
*********
*********
~