Commodore 64 Subroutine Cookbook PDF
Commodore 64 Subroutine Cookbook PDF
SUBROUTINE COOKBOOK
DAVID D. BUSCH
Note to Authors
Busch, David D.
Commodore 64 subroutine cookbook.
Incl udes index.
1. Commodore 64 (Computer)-Programming. 2. Basic (Computer program language) 3. Subroutines (Computer programs) I. Title: Commodore sixty-four subroutine cook book.
QA76.8.C64B87 1984 001.64'2 84-2775
ISBN 0-89303-383-9
1098 765432 1
Preface
Introduction
1
2
3
3
4
~ USING JOYSTICKS
Joystick Subroutine
Move Object Left, Right
Move Object All Directions
Drawing Subroutine
7
8
12
16
19
25
~ USING SOUND
Music
Siren
Computer Sound
Saucer Sound
Klaxon
Gunfire
37
55
26
29
31
40
43
45
48
50
52
iii
56
58
61
63
65
69
70
73
BASIC TRICKS
77
Number Input
Letter Input
String Sort
Number Sort
Array Loader
Super Saver
78
80
82
84
86
89
93
Deal Cards
Random Range
94
97
~~A~
D~
100
102
Delay Loop
DATA FILES
Data Files
Sequential
Sequential
Sequential
Sequential
107
11 0
File-Write to Tape
File-Read from Tape
File-Write to Disk
File-Read from Disk
114
115
117
119
123
124
126
128
130
133
134
136
138
140
142
144
146
149
151
153
155
156
158
160
162
164
165
iv
169
171
Peek Bit
Bit Displayer
Bit to One
Bit to Zero
Reverse Bit
Binary to Decimal
Rounder
172
174
175
177
178
180
il~ COMMUNICAnONS
Program Transfer
Terminal
183
184
186
GLOSSARY
189
INDEX
193
How many times have you looked over a program listing in a magazine and thought, "Gee,
I could have saved a lot of time if I'd used this joystick subroutine in myown game program!"
Did you read an explanation of how to redefine your computer's character set to new and
exciting shapes, only to wonder, "Well, I think I understand how it works-but how do I actually do it?"
Worse, do you find that examples are too complex to understand or that tightly packed programs that you try to dissect are so interwoven and poorly commented that it's impossible
to extract the purpose of each statement? Have you been reading a lot of useful tips and programming tricks but losttrack of them because they were scattered among a few dozen books
and magazines?
This book may be the reference you need and may serve as your shortcut to programming
proficiency. Herein are a variety of programming "recipes" in the form of BASIC subroutines
that, for the most part, perform only a single task. Useful functions are laid out in subroutines
that you can transplant directly to your own programs.
In most cases, the routines are presented in simply constructed lines with only one or two
statements per line and no extraneous material. That makes it easy for you to look at the
routines, and discover on your own the function of each statement. But, to make sure that
you grasp each concept, there is a line-by-line description and an explanation of the important
variables used in each subroutine.
Some of the information in this book is available elsewhere, but you'd have to compile
a huge stack of material to collect all of it in one place. Instead of searching through back
issues of magazines, the reader can thumb through the Contents or Index, and find out how
to simulate joysticks or paddles, generate specific sound effects, program character sets, or
perform various types of sorts.
Most subroutine books concentrate on "general" business or personal routines. Those are
inc! uded here, too, but we've also emphasized Commodore-specific tips aimed at your special
needs. New capabilities have been added to Commodore BASIC. Special features such as
repeating keys, PEEKing colors or characters at a specific location, or changing screen and
border combinations are covered. Programming the special function keys and using the built
in real-time clock are also included.
Whether you're already expert in BASIC programming and looking for a handy reference
guide or a new user seekingaccess to sophisticated subroutine tricks, this book should satisfy
your hunger.
vi
. ,J
Be forewarned. This book is unlike any other collection of subroutines that you might
have seen before. Herein are 70 useful, ready-to-transplant subroutines and programming tips that you can use to make your own programs sizzle with joystick action or
resound with music. These are Commodore 64 specific routines that take the mystery
out of using function keys, designing your own character sets, and other special Commodore 64 features.
Most "sugfolJtine" books are top.-heavy with exotic math functions and rarely used
s19~arprograms. Those were fine back iO the days when microcomputers were used
:,......--~'primarily by scientists, computer nuts, andbther high-tech types who doted on newer
and better ways of doing Fast Fourier transforms.
However, the Commodore 64, while it is a powerful, capable microcomputer, is being
sold to a broad range of users. Many only want to play games. Many more are interested
in learning programming but may have a skimpy technical background otherwise. Then,
there are those of you who really do understand computers but would like to avoid
reinventing the wheel.
The Commodore 64 Subroutine Cookbook is meant for all of you. There are some
general, useful routines included here. But, the book also bristles with modules designed
specifically to perform some sorely needed tasks for the Commodore 64 alone.
Nine subroutines are included that add crucial BASIC functions that were left out of
PET 2.0 BASIC. You can now simulate the INSTR function of other BASICs, allowing
you to search a string of characters for a shorter string. SWAP variable values. Enter
commas into strings through an innovative INPUT routine.
Confused even by the most lucid explanations of using the joysticks to manipulate objects .
on the screen? Justtransplant one of FOUR joystick routines included in this book. We even
show you how to move your missiles and enemy aliens around on the screen.
If you find that even the Commodore 64's several hundred alphanumeric, graphics,
and special characters aren't enough for you, and you'd like to design your own special
characters, take heart. You don't need to comprehend all the gory details. A module
is included which you can use to redefine up to five characters with no problems. Using
the Commodore 64's real-time clock to measure elapsed time or to control outside events
is also provided for. Generate musical notes within your own programs-or add sound
effects. Ready-made subroutines are provided for your use.
vii
Or, manipulate your Commodore 64 to your heart's content. One subroutine will
automatically set screen and border colors. Blank the computer's screen, while preserving the data stored there. Turn the repeat key feature on and off.
.
Games players will find tips on routines that spice up their own arcade-quality games,
while those interested in programming for business will revel in the user-friendly input
routines, menus, and sort routines.
More advanced programmers can use several routines as utilities to make their work
easier, while doing sophisticated "soft" POKing of individual bits within a multipurpose Commodore 64 register.
We've gone light on the "basic" subroutines, although plenty of the more important
conversion and financial routines are provided. The emphasis here is on modules you
can't find anywhere else but which will help you improve your programming
immediately.
While several routines explain how to use the joysticks with the Commodore 64, this
book does not include a matching paddle routine. Paddle reading is very unreliable from
BASIC and is not recommended. Commodore has a nice machine language paddle
routine in its Programmer's Reference Guide that you can incorporate into your programs if you wish.
Use of Commodore's special type of character, called "sprites," is not addressed here,
either. Sprite graphics allow defining screen objects that can be moved about the screen
by the user and are particularly useful for games. However, while the feature is very powerful, BASIC is much too slow to handle moving them around the screen for any serious applications. In addition, designing sprites and moving them is complex, and well beyond the
"subroutine" scope of this book. Typical sprite editor programs, such as that found in Tim
Onosko's "Commodore 64: Getting the Most From It" (Robert J. Brady Company) are f.i.ve
or six pages long. Commodore also has a very good sprite program in its Disk Bonus pack,
and a lengthy discussion of sprites in its Programmer's Reference Guide.
It is possible to write some very sophisticated, fast-moving games with BASIC using
user-defined characters, however. This book has a handy subroutine that lets you define
five characters of your own, and other modules show you how to manipulate characters
on the screen.
Sorting is another task that is typically very slow in BASIC. However, because of the
great demand for this routine, two sorts are included here. For limited-size lists, one
of them should be entirely acceptable.
viii
In doing so, it may be convenient to relocate them. Some utilities are available to
renumber programs for you as an aid to relocating them.
To make things easier, the routines are divided into sections. The basic routine itself
is clearly labelled. This portion may be renumbered and placed wherever convenient.
If renumbering manually, make sure the GOTO's and GOSUB's in the new modules
are correct. You don't want a line that reads: "1000 GET A$:IF A$ = ""GOTO 160".
Another section of each subroutine will usually be labelled "Initialization." These
lines will contain values that must be set once during a program, before the routine is
run. Or, the variables will be those that must be defined by your program before calling
the subroutine. Frequemly, these lines can be deleted or an equivalent line placed Within
your own program. The explanation with each subroutine tells the purpose of the
important variables.
The purpose of all the variables that you need to define, as well as the variable returned
by the subroutine for your program's use, is explained as well. Because the operation
of many subroutines is rather complex, some of the variables used only internally, as
well as various operations, may not be explained. This should be rare, as the line-byline descriptions cover nearly all the functions of every program. However, ifthis book
does not tell you what a variable does, it is information you do not need to know in
order to use the subroutine.
In some cases there are several related routines. For example, there are four joystick
routines. Some of the concepts are explained only once. You will be directed to look
at previous subroutines for longer explanations at times. This allows you to access the
routines in any order, without reading the entire book.
All the odd special Commodore 64 characters have been left out of this book. In some
cases, CHR$(147) is used for the "clear screen" symbol (reversed heart), while CHR$(17)
is used for "cursor down" (reversed Q). Both will perform their proper function, the
same as the actual symbols. Deleting the extra graphics makes the subroutines shorter
and easier to understand. You may want to add various cursor controls and color controls to the routines for your own use as programs are developed. This is a subroutine
cookbook; the finishing touches of the meal are up to you.
Variable names have been chosen, when possible, to reflect their functions in the
subroutines. In most cases, the variable names from one subroutine do not conflict with
those of another. However, when writing a complex program using several of these
modules, you should check to see that the same variable is not used twice for different
purposes. Keep in mind that only the first two letters are significant in Commodore 64
BASIC. So, PAYMENT, used in one subroutine, is actually the same as PAID, which might
be used in a second. You should take this precaution with any program you write,
whether "foreign" subroutines are being transplanted or not.
If you are eager to get started and have some experience in programming, you might
want to skip ahead to any subroutine that looks tempting. Those who are less sure of
themselves will want to start with Chapter 1, which discusses three ways of merging
an existing library of subroutines within your own programs.
Good luck. You should find this book a shortcut to programming proficiency. To
paraphrase a common saying, if you use a subroutine correctly three times, it will
a permanent part of your vocabulary. Given a bit of practice, you can soon have allytiur
friends drooling over your programs and asking you for your favorite subroutine recipes.
ge
TRADEMARKS OF MATERIAL
MENTIONED IN THIS TEXT
nIlM~lf~illm~ Ull1IDlf@Ulli1liIIil~$)
Wlii1Iln Y@Ulllf
IPlf@~lf~m~
Once you have keyed in this coJllmand line, and pressed RETURN, the Commodore
64 wi II ask you to press PLAY and RECORD. Do so, and wait unti I the tape drive stops.
With the PLAY and RECORD buttons still depressed, type PRINT#l :CLOSE1 on the
keyboard and press RETURN. The cassette recorder will run for several more seconds
as the remaining data in the Commodore 64's buffer is written to tape and the file is
closed. You will now have an ASCII version of the subroutine on tape. Rewind the tape
and label it.
Next, load your main program into the Commodore 64. Mount the ASCII subroutine
tape in the cassette recorder, and TYPE OPEN1,l on the keyboard. Press RETURN. You
wi II be asked to press the PLAY button on the cassette recorder. When you have done
that, the recorder will run until the tape header with the filename is read ("ASCIIprog.name") and the recorder stops.
At this point, leave the PLAY key depressed. Next press CLR to clear the screen, and
type POKE 153,1 at the top of the screen, and press RETURN. The cassette drive will
run for a few seconds until the buffer is filled with characters. Now, alternately press
HOME and RETURN. Each time you do this, one of the subroutine lines from the buffer wi II be added to the main program in memory. When the buffer is empty, the recorder
will start again, and additional data read into the buffer. Repeat pressing HOME and
RETURN until the end of the fi Ie mark is sensed. At this point, a SYNTAX error will be
displayed on the screen.
Congratulations! You now have appended the subroutine to the main program with
all the program pointers properly adjusted. LIST the program to check. Rewind your
ASCII subroutine tape to make it ready to append to another main program. You can
repeat these steps as many times as necessary to add several subroutines to your main
program.
*********************
*
*
*
COMPOUND INTEREST
*
*
*
*********************
+ + VARIABLES ++
RATE: INTEREST RATE
YEARS: YEARS COMPOUNDED
FUTURE: FUTURE VALUE
AMOUNT: AMOUNT TO BE COMPOUNDED
***
INITIALIZE
***
150 RATE = 10
160 AMOUNT = 1000
170 PERIOD = 365
180 YEARS = 10
190 GOTO 260
200 REM *** SUBROUTINE ***
210 RATE = RATE/l00
220 FUTURE = AMOUNT* ( 1 + RATE/PERIODS) [ (PERIODS
*YEARS) : LOAN = PAYMENT*(l-( 1 + RATE) "-NUMBER) /RATE
230 FUTURE = INT (FUTURE* 100
240 RETURN
+ . 5) /100
II ;
FUTURE
JOYSTICK SUBROUTINE
WHAT IT DOES
Variables
CSCREEN: Start position in memory of a map of the color of each Commodore 64
screen location
CHAR: Start position in memory of a map of which characters are displayed in each
Commodore 64 screen location
E: End of character memory
B1: Current position of Object #1
B2: Current position of Object #2
DF: The difference between (SCREEN and CHAR
M 1: Direction of move for Object #1, to be used to increment B1
Using Joysticks / 9
M2: Direction of move for Object #2, to be used to increment B2
F1: Status of fire button #1
F2: Status of fire button #2.
This subroutine prints a ball character (81 in the Commodore 64 character set) on the
screen. You may change the character by substituting some other number for the 81
in line 510. Or, substitute variable CURSR for the 81, and define CURSR to any character
you wish.
The routine leaves a "trail" of the character behind it. You can erase this by POKing
B1-M 1 with 32. Look at the following subroutines for a more complete use of this feature.
line 110: Calculate the difference between the start of screen memory and character
memory.
lines 290 to 300: Peek registers which store status of joystick 1 and joystick 2.
lines 310 to 320: Look at bit which tells whether FI RE button of either joystick is pressed. NOTE: Using the AND operator and bit manipulation are explained much more
thoroughly in Chapters 5 and 11.
lines 330 to 340: Determine status of each joystick's switches.
lines 350 to 420: Depending on value of joystick status variable, J1 and J2, movementofobject is defined as +40 (down one whole row), -40 (up one whole row), + 1
(one position to the right), or -1 (one position to the left).
lines 450 to 460: Clear screen and access the subroutine.
lines 470 to 480: If either FIRE button is pressed, clear the screen. Your program could
initiate some other action, such as releasing a missile.
lines 490 to 500: Update position of object, B1 and B2. If position is less than beginning of character memory, B, or greater than the end, E, negate this move.
lines 510 to 540: POKE new position of object, B1 or B2, with character desired, in
this case the CHR$(81), "ball" character. Then POKE the corresponding position in color
memory with a color, different for each joystick.
line 550: Go back and repeat.
You Supply
B1 or B2: Current position of object. This will be a number between CHAR and E.
Your program should always check to make sure that B1 is never less than CHAR
or greater than E. You may want to define B1 = CHAR at the beginning of the program to start in the upper left. That is done in this subroutine. Or, choose some other
position. Each movement of the cursor is made by changing the value of B1 or B2,
and then POKing B1 or B2 with the number of the character you want. Erase B1 or
B2 from its old position by POKing its former value with 32 (a space).
Using Joysticks / 11
RESULT
10 REM
20 REM
30 REM
***********************
*
* JOYSTICK
*
SUBROUTINE
*
*
40 REM
50 REM
***********************
60 REM
70 CSCREEN = 55296
80 CHAR = 1024
90 B1 = CHAR: B2 = CHAR
100 B CHAR: E CHAR + 1000
110 DF = CSCREEN-CHAR
120 GOTO 450
130
140
150
160
170
180
190
200
230
240
250
260
REM ---------------------------REM
+ + VARIABLES + +
F1:
STATUS OF FIRE BUTTON 1
REM
F2:
STATUS OF FIRE BUTTON 2
REM
REM
M1:
MOVE FOR JOY 1
REM
M2:
MOVE FOR JOY 2
B1:
REM
POST ION FOR OBJECT 1
B2:
REM
POSITION FOR OBJECT 2
REM
CSCREEN: START OF COLOR MEMORY
CHAR:
REM
START OF CHARACTER MEMORY
E: END OF CHARACTER MEMORY
REM
REM
Jl=PEEK(56320)
J2 = PEEK( 56321)
Fl=Jl AND 16
F2 = J2 AND 16
Jl=15-(J1AND15)
J2=15-(J2 AND 15)
IF J1=1 THEN Ml=-40:GOTO 390
IF J1 = 2 THEN Ml = 40: GOTO 390
IF J1 = 4 THEN Ml = -1: GOTO 390
IF J1=8 THEN Ml=l:GOTO 390
IF J2 = 1 THEN M2 = -40: RETURN
IF J2 = 2 THEN M2 = 40: RETURN
IF J2 4 THEN M2 -1: RETURN
IF J2 = 8 THEN M2 = 1: RETURN
RETURN
440 REM
450
460
470
480
490
500
510
520
530
540
550
PRINT CHR$(147)
GOSUB 290
IF Fl=O THEN PRINT CHR$(147)
IF F2=0 THEN PRINT CHR$(147)
Bl=Bl+Ml: IF Bl<B OR Bl>E THEN Bl=Bl-Ml
B2 =B2 + M2: IF B2 <B OR B2>E THEN B2 =B2-M2
POKE Bl,81
POKE Bl+DF,3
POKE B2,81
POKE B2 + DF ,5
GOTO 460
WHAT IT DOES
Moves object left and right only.
Variables
Using Joysticks / 13
You Supply
Just move joystick. ROW can be defined as the screen row on which the object moves.
CURSR can be defined as any character you wish, while CO will be the cursor color.
CO should be the color value you wish, minus one.
RESULT
Object will move on screen under joystick control, left or right only,
Using Joysticks / 15
10 REM ******************
*
20 REM *
30 REM *
MOVE OBJECT *
40 REM * LEFT OR RIGHT *
50 REM *
*
60 REM ******************
70 REM -----------------------------80 REM
+ + VARIABLES + +
ROW:
ROW TO MOVE IN
90 REM
BEGINNING OF THAT ROW
100 REM B:
110 REM E:
END OF THAT ROW
POSITION OF CURSOR
120 REM Bl:
CURSOR CHARACTER
130 REM CURSR:
140 REM CO:
CURSOR COLOR
DIRECTION OF MOVE
150 REM MOVE:
160 REM CSCREEN: COLOR MEMORY
170 REM CHAR:
CHARACTER MEMORY
CSCREEN-CHAR
180 REM DF:
190 REM
200 REM -----------------------------210 REM *** INITIALIZE ***
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
DIM D(10,2)
DATA 0,0,0,-1,0,0,0,1,0,0
FOR X= 1 TO 10
READ D(X,l)
NEXT X
PRINT CHR$(147)
CSCREEN = 55296
CHAR = 1024
ROW=5
Bl = CHAR + Row*40
E=Bl+39
B=Bl
DF = CSCREEN-CHAR
POKE 53281,1
CURSR=43:CO=2
GO TO 450
JV = PEEK( 56320)
F1 = JVAND16
Jl=15-(JVAND15)
MOVE=D(Jl,l)
RETURN
GOSUB 390
IF MOVE < > 0 THEN POKE B1,32
B1=B1+MOVE
IF B1 < B OR B1 > E THEN B1 = B1-MOVE
Variables
CSCREEN: The position in memory of the start of the color memory map
CHAR: The position in memory of the start of the character memory map
E: End of screen in memory
B1: Current position of cursor
DF: The difference between CSCREEN and CHAR
MOVE: Direction of move, to be used to increment B1
CURSR: Cursor character
CO: Cursor color.
This subroutine prints a plus sign, CHR$(43), in the Commodore 64 character set,
on the screen. You may change the character by substituting some other number for
the 43 in the definition for CURSR in line 310.
The routine leaves a "trail" of the character behind it. You can erase this by POKing
B1-MOVE with 32
Using Joysticks / 17
You Supply
Simply move joysticks. Define CURSR and CO to provide cursor character and color
of your choice.
RESULT
Object will move on screen.
10
20
30
40
REM
REM
REM
REM
******************
*
* MOVE OBJECT
* ALL DIRECTIONS
*
*
*
*
*
50 REM
60 REM ******************
70 REM -----------------------------80 REM
+ + VARIABLES + +
CSCREEN: COLOR MEMORY
90 REM
CHAR:
CHARACTER MEMORY
100 REM
110 REM
DF:
CSCREEN-CHAR
120 REM
Bl:
POSITION OF CURSOR
MOVE:
DIRECTION OF MOVE
130 REM
140 REM
CURSR:
CURSOR CHARACTER
CO:
CURSOR COLOR
150 REM
160 REM
170 REM -----------------------------180 REM
Using Joysticks / 19
190
200
210
220
230
240
250
260
270
280
290
]00
310
320
DIM D(10,2)
DATA -40,40,0,-1,-41,]9,0,1,-39,41
FOR X= 1 TO 10
READ D(X, 1)
NEXT X
PRINT CHR$(147)
CSCREEN = 55296
CHAR = 1024
E = CHAR + 1000: B = CHAR
Bl= CHAR
DF = CSCREEN-CHAR
POKE 53281,1
CURSR=43:CO=2
GO TO 400
330 REM
340
350
360
370
380
JV = PEEK ( 56320)
F1=JVAND16
Jl=15-(JVAND15)
MOVE=D(Jl,l)
RETURN
390 REM
400
410
420
430
440
450
GOSUB 340
Bl=Bl+MOVE
IF Bl<B OR Bl>E THEN Bl=Bl-MOVE
POKE Bl, CURSR
POKE Bl + DF , CO
GOTO 400
DRA~NGSUBROUTINE
WHAT IT DOES
Variables
You Supply
CURSR: Current cursor character. This number is POKEd into B1 to paint on the
screen.
CO: Current cursor color.
RESULT
Drawing on screen, with variety of colors and cursor characters.
10
20
30
40
50
REM
REM
REM
REM
REM
*********
*
*
* DRAW *
*
*
*********
DIM D(10,2)
DATA -40,40,0,-1,-41,39,0,1,-39,41
FOR X=l TO 10
READ D(X,l)
NEXT X
V=53248
PRINT CHR$(147)
B1=1024
MOVE=l
POKE 53281,1
VOLUME = 54296
VCE = 54273
WAVE = 54276
ATTACK = 54277
SUS = 54278
CURSR=43:CO=2
GOTO 410
JV=PEEK(56320)
F1=JVAND16
J1=15-(JVAND15)
JV=PEEK(56321)
F2=JVAND16
J2=15-(JVAND15)
RETURN
GOSUB 330
GET A$: IF A$ < > " " THEN GOSUB 540
GOSUB 600
IF D(J1,1) < >0 THEN MOVE=D(J1,1)
B1 = B1 + MOVE
IF B1>2022 THEN B1=B1+ (D(J1,l)*-l)
IF B1 < 1024 THEN B1=B1+ (D(J1,l)*-l)
IF B1>2022 THEN B1=B1+ (D(J1,l)*-l)
IF B1< 1024 THEN B1=B1+ (D(J1,l)*-l)
POKE B1, CURSR: POKE B1+54272,CO
IF CO = 1 THEN POKE B1 + 54272,5: POKE B1 + 54272, CO
IF F1=0 THEN PRINT CHR$(147)
GOTO 410
IF A$< "1" OR A$> "8" GOTO 570
CO=VAL(A$)-l
RETURN
CURSR=ASC(A$)
RETURN
POKE VOLUME, 15
POKE WAVE, 33
POKE ATTACK, 128
POKE SUS, 128
POKE VCE, 72
POKE VOLUME, 0
RETURN
~
~
0
0
@
0
TIME SET
WHAT IT DOES
Sets Commodore 64 real-time clock.
Variables
HR$: Current hours
MINUTE$: Current minutes
TI$: Commodore 64 real-time clock value.
You Supply
Subroutine asks for hours and minutes.
RESULT
Internal clock set to correct time.
************
*
* TIME
*
SET
*
*
*
40 REM
50 REM
60 REM ---------------------------70 REM
+ + VARIABLES + +
HOURS
80 REM
HR$
90 REM
MINUTE$: MINUTES
100 REM TI$:
CURRENT TIME
110 REM
************
350 REM
ELAPSED TIME
WHAT IT DOES
Measures difference between two times.
Variables
You Supply
Your program should set TS to equal TI when you wish to start timing. When the end
of the timing cycle is over, call the subroutine.
RESULT
Elapsed time is measured.
10
20
30
40
50
60
REM ****************
REM *
*
REM * ELAPSED TIME *
REM *
*
REM ****************
GOTO 240
TF=TI
FS=INTTF-TS)/60)
MIN= INT(FS/60)
SEC=FS-(MIN*60)
PRINT TAB(2) "IT TOOK YOU" jMIN
PRINT TAB(2) "MIN. AND" jSECj "SEC."
RETURN
TS=TI
GET A$: IF A$ = "" GOTO 250
GOSUB 160
GOTO 240
TIMER
WHAT IT DOES
Sets computer as a timer.
Variables
You Supply
Answer the requests from the prompts. You also might want to call a sound subroutine
of your choice atLine 570, to provide an audible alarm. Several sound routines are provided in the next section of this book.
RESULT
Commodore 64 signals at end of requested time interval.
10 REM
20 REM
30 REM
40 REM
50
60
70
80
*********
*
*
* TIMER *
*
*
*********
REM
GOTO 590
REM
REM
90 REM
100 REM
110 REM
120 REM
++
FH$:
FM$:
FS$:
FT$:
VARIABLES ++
FINISH HOUR
FINISH MINUTES
FINISH SECONDS
FINISH TIME
130 REM
140 REM ---------------------------150 REM
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
345 REM
350
360
370
380
390
400
410
420
430
440
450
460
470
480
490
500
510
520
530
540
550
560
570
33
590 PRINT
10
20
30
40
50
60
70
80
POKE
POKE
POKE
POKE
POKE
POKE
POKE
POKE
54296, 15
54273,34
54272,75
54276,65
54275,12
54274,200
54277,130
54278,66
(Sets volume)
(Plays middle
C on Voice 1)
(Sets pulse wave form)
(Sets hi pulserate)
(Sets low pulserate)
(Sets attack/decay rate)
(Sets sustain/release rate)
Length of the note is yet another parameter that must be taken care of by your programming, with a FOR-NEXT delay loop, or some other means. It's nice to have that
much control over a sound, isn't it? But who would want to do all that programming
three times over (for each voice)? Granted, every line shown above is not needed for
every note. Some are required only when you want to change some of the parameters
for a given voice. However, keeping track can be a pain, even when "offsets" and special
programming tricks are used to reduce the work.
There are several music "synthesizer" programs that will allow you to experiment
with the sound capabilities of this computer. These are long, complex, and beyond the
scope of this subroutine "cookbook."
The intent is to provide you with "plug in" subroutines that you can use in your own
programs immediately, even if you can't tell a synthesizer from photosynthesis. This
chapter contains five subroutines that have broad application in many games
programs-or which can be used to spice up your general programming efforts.
The fi rst routi ne generates musical notes when the keys of the home row, and the row
above, are pressed. Others produce a grating siren sound, a madcap computer gone
berserk, eerie flying saucer noises, and other effects.
You may want to experiment with each of these, using some of the suggestions provided, or with ideas of your own. Change the val ues of FOR-N EXT loops. Use different
voices, as suggested. You should be able to develop new sounds on your own, until
a whole library of sound effects is available.
In general, music and sound effects generation on the Commodore 64 is accomplished
by POKing various values to several memory locations, or registers. For example, the
volume of all three voices can be controlled by POKing values from 0 to 15 in location
54296. Unfortunately, the Commodore 64 does not allow you to control the volume
of each voice separately. A 0 will "turn off" all the voices at once, while POKing 15
to 54296 will produce maximum volume.
The three music voice registers are located in pairs at 54272/54273,54279/54280,
and 54286/53287. POKing pairs of values to these registers will produce musical notes
that more or less correspond to the notes of the musical scale. The actual values are
listed on pages 163-164 of the Commodore 64 User's Guide supplied with the computer.
In addition, you also need to POKE a waveform, to registers located at 54276,54283,
and 54290, for the three voices, respectively. A value of 17 POKed to any of these
registers will produce a "triangle" type waveform, while 33 will generate a "sawtooth"
waveform. A 65 produces a pulse wave, with 129 delivering nothing but a randomsounding noise. Try substituting each of these in various sound routines to hear the
changes for yourself.
But wait! There's more. When using pulse waveforms, each voice has yet one more
pair of registers that need to be POKEd to supply pulse rate. Finally, you may choose
attack and decay rates. Each are separate values but, since the combinations of the two
produce unique numbers, you may add your chosen attack rate to your chosen decay
rate and POKE a single number to one register for each voice. Sustain/release are set
up in a similar manner.
Anotherfactor, the length of time each note is played, is controlled by your program.
A note can begin when you POKE a value 1 to 15 into the volume register, and end
when a 0 is POKEd to that location. In between, you might have a FOR-NEXT loop providing the desired amount of delay. This could be varied by your program, as you desire:
10 INPUT "LENGTH OF NOTE WANTED (1 TO 10) " ; DELAY
20 GOSUB 100
Now, the volume is still on high, but we cannot hear the note because the voice register
is turned off. The first example used is a way of controlling the length of all the notes
being played by all the voices simultaneously. This second example shows how to vary
the length of a note played by an individual voice, without altering those of the other
voices. Combinations of these two can be used to produce sophisticated sounds and
melodies.
MUSIC
WHAT IT DOES
Uses keyboard to generate various musical notes.
Variables
VOLUME: Address to POKE volume
VCE: Voice currently being used
LTH: Length of note.
You Supply
LTH controls the length of the note. A larger value produces a longer note. You change
to another voice by making the following substitutions:
VCE = 54275
POKE 54283,33
POKE 54284,128
POKE 54285,128
VCE = 54287
POKE 54290,33
POKE 54291,128
POKE 54292, 128
RESULT
Music played from Commodore 64 synthesizer.
*****************
10 REM
20 REM
30 REM
MUSICAL NOTES
40 REM
50 REM ************~****
60 REM ----------------------------70 REM
VARIABLES
80 REM
VOLUME:
LOUDNESS REGISTER
90 REM
VCE:
VOICE
100 REM
LTH:
LENGTH OF NOTE
110 REM
120 REM -----------------------------
*
*
*
*
*
*
++
130 REM
140
150
160
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
VOLUME = 54296
VCE = 54273
LTH=200
POKE 54276,33
DIM NME(14) ,NT$(14) ,p(14)
FOR N= 1 TO 14
READ NME(N)
NEXT N
FOR N= 1 TO 14
READ NT$(N)
NEXT N
FOR N=l TO 14
READ P(N)
NEXT N
DATA3,3,4,4,5,6,6,7,7,1,1,2,3,3
DATAA,W,S,E,D,F,T,G,Y,H,U,J,K,O
DATA 34,36,38,40,43,45,48,51,54,57,61,64,68,72
GOTO 480
320 REM
330
340
350
360
370
380
390
400
410
420
430
440
450
460
++
POKE 54277,128
POKE 54278,128
GET A$:IF A$= If II GOTO 350
IF A$=CHR$(13) THEN RETURN
FOR N= 1 TO 14
IF A$=NT$(N) GOTO 410
NEXT N
GOTO 350
POKE VOLUME, 15
POKE VCE,P(N)
FOR DELAY = 1 TO LTH:NEXT DELAY
POKE VOLUME, 0
POKE VCE,O
GOTO 350
Using Sound /
470 REM
43
SIREN
WHAT IT DOES
Variables
You Supply
No user changes required. However, voice of siren may be changed by making the
following substitutions:
H1: 54280
L1: 54279
W1: 54283
A1: 54284
51: 54285
RESULT
Siren sound emitted for game play or other applications.
10 REM
*********
20 REM
30 REM
40
50
55
60
70
80
*
*
* SIREN *
*
*
REM
REM
REM ------------------------------------REM
+ + VARIABLES + +
REM
VOLUME: VOLUME REGISTER
REM
Hl:
VOICE # 1, HIGH
*********
90 REM
100 REM
110 REM
120 REM
130 REM
Ll:
Wl:
Al:
Sl:
SAW:
VOICE # 1, LOW
WAVE FORM VOICE 1
ATTACK/DECAY VOICE 1
SUSTAIN/RELEASE VOICE 1
SAWTOOTH WAVEFORM
H1 = 54273
L1 = 54272
W1= 54276
Al = 54277
Sl = 54278
220 SAW=33
230 GOTO 410
240 REM
Using Sound / 45
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
POKE VOLUME, 15
POKE Wi, SAW
POKE Ai, 16
POKE Sl, 16
POKE Hi, 36
FOR J = 1 TO 5
FOR N=34 TO 72
POKE Hl,N
POKE Ll,N+75
NEXT N
FOR N=72 TO 34 STEP -1
POKE Hi, N
FOR 1=1 TO 40:NEXT I
NEXT N
NEXT J
400 REM
COMPUTER SOUND
WHAT IT DOES
Computer-like sound, for games, other applications.
Variables
You Supply
LTH may be redefined to produce longer computer sound effect.
RESULT
Computer-like sounds emitted for game play or other applications.
10 REM
20 REM
30 REM
40 REM
50 REM
******************
*
* COMPUTER
*
SOUND
*
*
*
******************
80 REM
90 REM
Hl-H3:
100 REM
L1-L3 :
110 REM
Wl-W3:
120 REM
Al-A3:
130 REM
Sl-S3:
140 REM
SAW:
SAWTOOTH WAVEFORM
Using Sound / 47
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
340
350
360
370
380
390
400
410
420
430
440
450
460
470
LTH=100
VOLUME = 54296
H1=54273
Ll = 54272
Wl = 54276
H2 = 54280
L2 = 54279
W2 = 54283
H3 = 54287
L3 = 54286
W3 = 54290
A1 = 54277
A2 = 54284
A3 = 54291
Sl= 54278
S2 = 54285
S3 = 54292
TRIANGLE = 17
SAw=33
POKE VOLUME, 15
POKE W1, TRI
POKE W2, TRI
POKE W3 , SAW
POKE Al, 128
POKE Sl, 128
POKE A2, 128
POKE S2, 128
POKE A3, 128
POKE A4,128
POKE H1,36
GOTO 610
FOR N= 1 TO LTH
R1 = INT(RND( 1) *35)
R2=INT(RND(1)*35)
R3=INT(RND(1)*35)
POKE L1,R1+70:POKE Hl,Rl+30
POKE L2,R2+70:POKE H2,R2+30
POKE L3,R3+70:POKE H3,R3+30
FOR J=l TO INT(RND(1)*15) : NEXT J
NEXT N
POKE VOLUME, 0
RETURN
SAUCER SOUND
WHAT IT DOES
Flying saucer-like sound, for games, other applications.
Variables
You Supply
No user changes recommended.
RESULT
Flying saucer-like sounds emitted for game play or other applications.
Using Sound / 49
10 REM
20 REM
30 REM
****************
*
* SAUCER
40 REM
SOUND
*
*
****************
50 REM
60 REM ---------------------------------70 REM
+ + VARIABLES + +
80 REM
VOLUME: VOLUME REGISTER
VOICE # 1, HIGH
H1:
90 REM
100 REM
11:
W1:
110 REM
VOICE
# 1,
LOW
120 REM
A1:
ATTACK/DECAY VOICE 1
130 REM
140 REM
Sl:
SAW:
SUSTAIN/RELEASE VOICE 1
SAWTOOTH WAVEFORM
KLAXON
WHAT IT DOES
Klaxon sound routine to produce sounds for games,
other applications.
Variables
You Supply
No user changes required.
RESULT
Klaxon sound emitted for game play or other applications.
Using Sound / 51
10 REM
20 REM
**********
*
30 REM
* KLAXON *
*
*
40 REM
50 REM
60 REM --------------------------------70 REM
+ + VARIABLES ++
VOLUME: VOLUME REGISTER
80 REM
VOICE # 1, HIGH
Hl:
90 REM
100 REM
Ll:
VOICE # 1, LOW
110 REM
Wl:
WAVE FORM VOICE 1
Al:
ATTACK/DECAY VOICE 1
120 REM
Sl:
130 REM
SUSTAIN/RELEASE VOICE 1
140 REM
SAW:
SAWTOOTH WAVEFORM
**********
180
190
200
210
VOLUME = 54296
Hl = 54273
L2 = 54272
Wl = 54276
220
230
240
250
260
270
Al = 54277
Sl = 54278
S2 = 54285
S3 = 54292
SAW=33
GOTO 420
280 REM
290
300
310
320
330
340
350
360
370
380
390
400
POKE VOLUME, 15
POKE Wl,SAW
POKE POKE Al, 128
POKE Sl, 128
FOR J=l TO 5
FOR N= 1 TO 100
POKE Hl, N/2 + 30
POKE Ll,N/2+70
NEXT N
NEXT J
POKE VOLUME, 0
RETURN
410 REM
GUNFIRE
WHAT IT DOES
Gunfire sound routine to produce sounds for games,
other applications.
Variables
You Supply
No user changes required. Noise voice must be used.
RESULT
Gunfire sound emitted for game play or other applications.
REM
REM
REM
REM
***********
*
*
* GUNFIRE *
*
*
50 REM **********
55 REM --------------------------------60 REM
+ + VARIABLES ++
VOLUME: VOLUME REGISTER
70 REM
H1:
VOICE # 1, HIGH
80 REM
11:
VOICE # 1, LOW
90 REM
100 REM
W1:
WAVE FORM VOICE 1
110 REM
A1:
ATTACK/DECAY VOICE 1
120 REM
Sl:
SUSTAIN/RELEASE VOICE 1
130 REM -----------------------------140 REM *** INITIALIZE ***
150
160
170
180
190
200
VOLUME = 54296
W1 = 54276
A1 = 54277
H1 = 54273
11 = 54272
GOTO 330
GOSUB 220
R= INT(RND( 1) *150)
FOR N=l TO R
NEXT N
GOTO 330
Variables
SCREEN: Screen color
BRDR: Border color
CCHARS: Character color.
You Supply
A value for SCREEN in the range 1 through 8. For convenience, the actual color names
may be used instead. Also, supply a value for BRDER, using the same scheme. To change
the character colors, define CCHAR as the desired color in the same manner.
RESULT
Screen, border, and character colors change.
*
*
*
*
140 REM
150
160
170
180
190
200
210
220
290 REM
300
312
323
330
DARK = 1: 'WHITE = 2
RED=3:CYAN=4
PURPLE = 5 : GREEN = 6
BLUE = 7 : YELLOW = 8
BACKGROUND = 53281
SURROUND = 53280
LTTERS=646
GOTO 300
240 REM
250
260
270
280
*
*
*
SCREEN = DARK
BRDER = BLUE
CCHARS = 'WHITE
GOSUB 250
COLOR PEEKER
WHAT IT DOES
Determines character color in a certain memory location.
Variables
COLR$(n): Color
ADDRESS: Location to PEEK.
11010001
00001111
00000001
01100001
00001111
00000001
You Supply
The memory location you wish to PEEK, variable ADDRESS. This is determined byadding CHOICE (the offset of the address you wish to look at) to CSCREEN (the start of
color memory). In the example, location 25 is used.
RESULT
Variable C will store the number of the key that is the same as that
in location ADDRESS. String array COLR$(C) will print the name of
that color.
10 REM
20 REM
.30 REM
40 REM
50 REM
****************
60 REM
***
*
*
*
COLOR PEEKER
*
*
*
****************
INITIALIZE
***
CSCREEN = 55296
CHOICE=25
ADDRESS = CSCREEN
GOTO 270
170
180
190
200
210
220
REM ---------------------------REM
+ + VARIABLES ++
REM
COLR$(N): COLOR
REM
ADDRESS: LOCATION TO PEEK
REM
REM
230 REM
240 C
+ CHOICE
250 RETURN
260 REM
270 PRINT
280 GOSUB 240
290 PRINT II COLOR
II ;
COLR$ (C)
DISPLAY TESTER
WHAT IT DOES
Variables
None.
You Supply
Set adjustments.
RESULT
Better display quality or rough diagnosis of a problem.
10
20
30
40
50
******************
REM
REM
REM
* DISPLAY TESTER *
REM
REM
*****************
60 REM
70 FOR N=l TO 8
80 READ COLR(N)
90 NEXT N
100 DATA 144,5,28,159,156,30,31,158
110 GOTO 410
120
130
140
150
160
REM ---------------------------REM
+ + VARIABLES ++
REM
NONE
REM
REM ----------------------------
170 REM
FOR ROW = 1 TO 24
FOR N = 1 TO 4
FOR CO=l TO 8
PRINT CHR$(COLR(CO)) i
PRINT CHR$(18) iCHR$(32) i
340
350
360
370
NEXT CO
NEXT N
PRINT
NEXT ROW
410 PRINT
420 GOSUB 180
SCREEN BLANKER
WHAT IT DOES
Allows blanking the Commodore 64 screen, while preserving data
printed there.
Variables
None.
You Supply
No user changes required.
RESULT
Screen image blanked.
10 REM
20 REM
30 REM
****************
*
*
BLANK SCREEN
*
*
40 REM
50 REM
60 GOTO 190
****************
++
++
100 REM
110 REM ---------------------------120 REM
190
200
210
220
230
PRINT
GOSUB 130
FOR N= 1 TO 1000
NEXT N
GOSUB 160
PROGRAM CHARACTERS
WHAT IT DOES
Variables
None.
o0 0 1 1 0 0 0
o0
100
01000
o 111 1
010 0 0
010 0 0
01000
o0 0 0 0
100
0 1 0
1 1 0
0 1 0
0 1 0
0 1 0
000
See the letter" A" in that pattern? Since each row is eight characters across, and each
character is either a zero or a one, it is convenient to think of each row as a byte and
to store it that way in memory. Eight consecutive bytes will store the eight rows needed
to describe a given character.
This is exactly what the Commodore 64 does. The information on the letter "A" begins
at memory location 53256 and continues for eight bytes. The first line above, 00011000,
in binary, is 24 in decimal. Similar eight-byte groups are found in memory to tell the
computer how to form all the alpha and graphics characters, including reversed
characters.
Unfortunately, characters are actually stored in ROM. We can READ the information
but not change it. However, when the Commodore 64 wants to find out how to build
a given character, it does not go directly to the proper ROM location. Instead, it checks
a RAM location, which tells it where to find the beginning of the character memory.
>
<
character.
character.
You Supply
New DATA lines corresponding to your redesigned characters. Layout your characters
in an 8 x 8 grid, as shown above, and convert each byte to binary. This can be done
by taking each of the eight bits, from right to left, and multiplying by 2 to the P power,
where P is the position, from the right, of that bit.
2 to
2 to
2 to
2 to
2 to
2 to
2 to
2 to
the
the
the
the
the
the
the
the
zeroth power
first power
second power
third power
fourth power
fifth power
sixth power
seventh power
(1 )
(2)
(4)
(0)
(16)
(0)
(0)
(128)
151 decimal
Total:
RESULT
Pressing "@", "!", II <", II _ " , and ">" keys, or using them in a
program will produce new, redefined characters.
10 REM
**************
20 REM
30 REM
40 REM
50 REM
* CHARACTERS *
*
*
**************
*** CHANGE
>
***
*** CHANGE
<
***
*** CHANGE
***
REPEAT KEYS
WHAT IT DOES
Changes repeat keys and cursor color
Variables
YES: Repeat all keys
NO: Don't repeat
SHADE: Color for cursor.
You Supply
Variable YES or NO
A value for SHADE, the cursor color.
RESULT
Either key repeat feature is turned ON, OFF, and cursor color
adjusted.
****************
*
* REPEAT
* CURSOR
KEYS,
COLOR
*
*
*
*
50 REM
60 REM
70 REM ---------------------------80 REM
++ VARIABLES ++
YES:
REPEAT KEYS
90 REM
100 REM
NO:
DON'T REPEAT
110 REM
SHADE: NEW COLOR OF CURSOR
****************
120 REM
130 REM ---------------------------140 REM
150 DARK = 1
160 WHITE=2
170
180
190
200
210
RED=3
CYAN=4
PURPLE = 5
GREEN=6
BLUE=7
220
230
240
250
260
270
YELLOW = 8
YES=128
NO=O
AGAIN=650
CURSR = 646
GO TO 340
280 REM
FUNCTION KEYS
WHAT IT DOES
Variables
A: Value of function key pressed.
You Supply
Subroutines as needed
Modifications to filter out unwanted keys.
RESULT
Pressing function key leads to various subroutines.
10 REM
20 REM
30 REM
40 REM
*****************
*
*
*
FUNCTION KEYS
*
*
*****************
50 REM
60 GOTO 140
100 REM
110 REM
DISK COMMAND
WHAT IT DOES
Displays a menu that user can choose from to carry out formatting
of new disk, scratching of unwanted programs from disk, initializing
disk, or validating disk.
Variables
NC: Number of menu choices.
You Supply
A value for NC whenever the menu is enlarged.
RESULT
Disk functions carried out automatically.
****************
40 REM
*
*
50 REM
****************
60 REM
30 REM
DISK COMMAND
*
*
70 NC=4
80 GOTO 300
90 REM ---------------------------100 REM
+ + VARIABLES + +
110 REM
120 REM
130 REM ---------------------------140 REM
**"
"**
" 3.
INITIALIZE"
300 PRINT
310 GOSUB 150
315 REM
PRINT CHR$(147)
PRINT" INSERT DISK TO"
PRINT "BE FORMATTED."
PRINT
GO TO 310
REM -SCRATCHPRINT CHR$(147)
OPEN15,8,15
580 OPEN15,8,15
590
600
610
620
PRINT#15," I"
CLOSE 15
GOTO 310
REM -VALIDATE-
NUMBER INPUT
WHAT IT DOES
Variables
I: Number entered
1$: String entered.
Basic Tricks / 79
Another less-than-perfect solution is to use a line like "10 INPUT A$:A = VAL(A$):IF
A < 1 GOTO 10". If the user enters alpha characters, the program loops back and the
input must be repeated.
This subroutine takes a different approach. It totally ignores non-numbers; if the
operator presses an illegal key, it isn't even echoed to the screen. The keyboard responds
only when numeric keys are pressed.
The secret is a GET A$ loop. If the user presses a number key, that letter is added to
1$. When A$ equals CHR$(13), a carriage return, then input is over. Otherwise, the loop
repeats allowing additional numeric entries.
When the subroutine ends, variable I will have the value of the user's entry.
You Supply
User may change the upper and lower limits in line 160 to restrict the range of numbers
to be entered. This might be useful when getting input for, say, a menu with only five
choices. All numbers over five, and all alpha characters would be ignored.
RESULT
Only user numeric input, in the form of positive numbers, is allowed.
10 REM
20 REM
]0 REM
40 REM
50 REM
****************
*
*
* NUMBER INPUT *
*
*
****************
60
I$=I$+A$
GOTO 140
I =VAL(I$) : PRINT
RETURN
220 REM
LETIERINPUT
WHAT IT DOES
Allows user to input only alpha characters.
Variables
1$: String entered.
Basic Tricks / 81
Line 170: Add key to previous entries.
Line 180: Go back for more entries.
Line 210: Access the subroutine.
You Supply
User may change the upper and lower limits in line 150 to restrict the range of alpha
characters that can be entered. This might be useful when getting input for, say, a game
like Mastermind(TM) where only the letters A-E are wanted. All numbers, graphics, and
alpha characters larger than E can be ignored.
RESULT
Only user alpha input is allowed.
10 REM
****************
40 REM
*
*
* LETTER INPUT *
*
*
50 REM
****************
20 REM
30 REM
90 REM
100 REM ----------------------110 GOTO 210
120 REM
II II
GO TO 130
II
A II OR A$ >
II
Z II GO TO 130
STRING SORT
WHAT IT DOES
Alphabetizes a list.
Variables
NU: Number of items to be sorted
US$(n): Array storing list to be sorted.
Basic Tricks / 83
Line 250: If the "higher" element, A$, is already smaller than B$, then B$ remains
where it is, and the inner loop steps off the next value of N 1.
Lines 260 to 270: If B$ is smaller than A$, then the two strings are swapped, with
B$ moving ahead one element, and A$ being pushed down one.
Lines 280 to 290: The inner and outer loops are incremented.
Lines 300 to 320: The sorted list is printed to the screen.
You Supply
Define N U, the number of items to be sorted
Supply the data for the array, US$(n).
RESULT
List is sorted alphabetically.
10 REM
***************
20 REM
30 REM
40 REM
*
*
*
STRING SORT
*
*
*
50 REM ***************
60 REM ---------------------------70 REM
+ + VARIABLES ++
NU:
NUMBER OF ITEMS SORTED
80 REM
US$(N): ARRAY WITH ITEMS
90 REM
100 REM
130 NU=10
140 DIM US$(NU)
150 GOTO 350
160 REM
II
ITEM
NUMBER SORT
WHAT IT DOES
Sort group of numbers by size.
Variables
NU: Number of items to be sorted
US(n): Array storing list to be sorted.
Basic Tricks / 85
sorts are easier to understand than string sorts, because simple number comparisons
are used. That is, 1237 is always larger than 32.6, and smaller than 7844. Gradually,
each member of the list "floats" up to its proper place in the array.
While such sorts are not very fast, with small lists of, say, 30 or 40 items, the speed
is satisfactory.
You Supply
Define NU, the number of items to be sorted
Supply the data for the array, US(n).
RESULT
List of numbers is sorted by size.
10 REM
20 REM
30 REM
40 REM
50 REM
***************
*
* NUMBER
*
SORT
*
*
*
***************
80 REM
90 REM
100 REM
+ + VARIABLES + +
NU:
NUMBER OF ITEMS SORTED
US(N): ARRAY WITH ITEMS
130 NU=10
140 DIM US(NU)
150 GOTO 350
160 REM
170
180
190
200
210
220
230
240
250
260
270
280
290
300
310
320
330
FOR ITEM = 1 TO NU
PRINT" ENTER # " ; ITEM
INPUT US(ITEM)
NEXT ITEM
FOR N=l TO NU
FOR N1 = 1 TO NU-N
A=US(N1)
B=US(N1+1)
IF A < B THEN GOTO 280
US(N1) =B
US(N1+1) =A
NEXT N1
NEXT N
FOR N=l TO NU
PRINT US(N)
NEXT N
RETURN
340 REM
ARRAY LOADER
WHAT IT DOES
Variables
NROWS: Number of rows in array
NCOLUMNS: Number of columns in array.
Once a data file has been assembled with such information, a routine is needed to
load it into an array where it can be manipulated, sorted, added to, or entries deleted.
This subroutine does exactly that. Although written for a string array, it can be converted
to a numeric array simply by deleting the variable type specifier, 1/$." That is,
DTA$(row,column) should become DTA(row,column), and A$ should be changed to A.
Study this example to learn more of how arrays work, as they are one of the most i mportant concepts in BASIC programming.
You Supply
The number of rows, NROWS, and number of columns, NCOLUMNS should be
specified. Data can be supplied from DATA lines or, better, read in from disk or tape.
RESULT
****************
*
* ARRAY
*
LOADER
*
*
*
40 REM
50 REM ****************
60 GOTO 280
INITIALIZE
***
NROWS=2
NCOLUMNS = 3
DATA JOE,2 PINE,232-4531,SAM, 1 ROE, 445-3622
DIM DTA$(NR,NC)
GOTO 280
190 REM
200
210
220
230
240
250
260
***
***
SUBROUTINE
***
270 REM
***
280 PRINT
290 GOSUB 200
300 PRINT r r NAME ADDRESS PHONE r
310
320
330
340
350
360
370
PRINT
FOR ROW 1 TO NROWS
FOR COL = 1 TO NCOL
PRINTDTA$(ROW,COL);" ";
NEXT COL
PRINT
NEXT ROW
***
Basic Tricks / 89
SUPER SAVER
WHAT IT DOES
SAVES program to disk.
Variables
F$: Name of your program.
You Supply
Define a filename, which should be 10 characters or less, to allow for the 6 characters
ofTl$. If your filename is longer than 10 characters, no error will be generated. Instead,
it will be shortened. For example, "TEST PROGRAM" might be SAVEd as "ST
PROGRAM123412."
WHAT IT DOES
File can be saved repeatedly under updated names.
***************
20 REM
30 REM
40 REM
*
*
* SUPER SAVER *
*
***************
50 REM
60 GOTO 170
170 PRINT
DEAL CARDS
WHAT IT DOES
Variables
DECK$(n): Deck of cards
CARD$: Card drawn from deck
DRAW: Random number.
Game Routines / 95
The routine starts off by setting NC (number of cards) to 52. In line 41 0, the computer
selects a number between 1 and NC (52 this time), and that element of DECK$(n)
becomes the card drawn. This leaves a "hole" in the deck at position DRAW. We fill
it up by taking the last card in the deck, which is DECK$(NC), and place it in
DECK$(DRAW). This leaves the "hole" at the end, but we then change NC to equal
NC-1, sothe computer will only draw from the elements 1 through 51 on the nexttime
through. Third time, it will choose 1 through 50, and so forth. It does not matter that
we have mixed up the order of the deck, as we wantthe cards shuffled in the first place.
Each element of DECK$(n) consists of a number, or face card name, plus the Commodore 64 CHR$ value for the suit (either 193,211,218 or 216-DATA in line 140).
This produces a full deck of 52 cards.
You Supply
No user input needed.
RESULT
Deck of 52 cards may be dealt out as needed.
FOR N= 1 TO 4
READ A
SUIT$(N) = CHR$(A)
NEXT N
FOR SUIT =1 TO 4
CU=CU+1
DECK$(CU) = "ACE OF "+SUIT$(SUIT)
CU=CU+1
DECK$(CU) = "KING OF "+SUIT$(SUIT)
CU=CU+1
DECK$(CU) = "QUEEN OF "+SUIT$(SUIT)
CU=CU+1
DECK$(CU) = "JACK OF "+SUIT$(SUIT)
FOR N=2 TO 10
CU=CU+1
DECK$(CU) =STR$(N) + " OF "+SUIT$(SUIT)
NEXT N
NEXT SUIT
NC=52
GOTO 470
IF NC < > 0 GOTO 410
CARD$= " "
PRINT" DECK GONE! ! "
RETURN
DRAW = INT(RND(l)*NC) +1
CARD$=DECK$(DRAW)
DECK$(DRAW) =DECK$(NC)
NC=NC-1
RETURN
Game Routines / 97
460 REM
470 PRINT
480 GOSUB 370
490 PRINT CARD$
RANDOM RANGE
WHAT IT DOES
Allows choosing random numbers in any range.
Variables
You Supply
Define HIGH and MINIMUM to set the limits for the random range you want.
RESULT
Only random numbers in the specified range will be produced.
10 REM ****************
20 REM *
*
30 REM * RANDOM RANGE *
40 REM *
*
50 REM ****************
60 REM -----------------------70 REM
+ + VARIABLES + +
80 REM
HIGH:
TOP OF RANGE
MINIMUM: BOTTOM OF RANGE
90 REM
100 REM
DF:
DIFFERENCE
110 REM
NUMBER CHOSEN
NU:
120 REM
130 REM -----------------------140 GO TO 230
150 REM *** INITIALIZE ***
160 HIGH = 100
170 MINIMUM = 15
180 DF=HIGH-MINIMUM+l
190 REM *** SUBROUTINE ***
200 NU=INT(RND(l)*DF) + MINIMUM
210 RETURN
220 REM *** YOUR PROGRAM BEGINS HERE ***
230 PRINT NU;
240 GOSUB 190
COIN FLIP
WHAT IT DOES
Flips coin, producing heads or tails.
Game Routines / 99
Variables
FLIP: Random value, either one or two
FLlP$: Name of side chosen
COIN$(n): Coin array.
You Supply
No user input needed.
RESULT
Coin flipping simulated.
10 REM
20 REM
30 REM
40 REM
50 REM
*************
*
*
COIN FLIP
*
*
*************
DICE
WHAT IT DOES
Variables
01: Value of Die #1
02: Value of Die #2
ROLL: Total of roll.
You Supply
Number of sides of die.
RESULT
N-sided dice are rolled, and the value of each plus total roll reported.
10
20
30
40
REM
REM
REM
REM
********
*
*
* DICE *
*
********
50 REM
60 GOTO 270
80 REM
Dl= INT(RND(l)*SIDES) +1
D2=INT(RND(1)*SIDES)+1
ROLL=D1+D2
REM *** DICE SOUND ***
POKE 36878,15
POKE 36874,150
FOR N= 1 TO 100:NEXT N
POKE 36877,255
FOR N=l TO 100:NEXT N
POKE 36877,0:POKE 36874,0
RETURN
PRINT
SIDES=6
GOSUB 150
PRINT" DIE # 1: " jD1
PRINT" DIE #2:" jD2
PRINT" TOTAL: " ;
PRINT ROLL
DELAY LOOP
WHAT IT DOES
Variables
DELAY: Initial delay
CHANGE: Amount of change.
You Supply
An initial value is needed for DELAY. A high number will start the program off very slowly. A lower numberwill produce a more moderate beginning speed. You also must define
the amount of CHANGE. Fractional numbers will cause DELAY to get smaller each time.
That is, if DELAY is 1000 at first, and CHANGE is .90, then DELAY will be set to 900
on the second time through the loop, 810 the third time, and 729 the third time.
As decimal fractions approach 1.0, the amount of speedup each time will be smaller,
producing a slower acceleration. Smaller fractions, such as .75 or even .50 will rev up
the speed quite quickly.
CHANGE can also be defined as a number larger than one. Setting it to 1.1 will slowly increase the delay each time. Any number larger than 1.5 (such as two or three) will
probably slow down the program much more than you desire.
RESULT
Program speeds up, or slows down gradually, at a rate selected by
user.
10 REM
20
30
REM
REM
40
50
REM
REM
*********
*
*
* DELAY *
*
*
*********
++
90 REM
100 REM
CHANGE:
++
AMOUNT OF CHANGE
PLUS OR MINUS
110 REM
120
REM ----------------------------
130 REM
=
=
FOR N 1 TO DELAY
NEXT N
DELAY DELAY*CHANGE
RETURN
If no device number is indicated, the computer assumes we mean device number one,
the "default" value. That is why your cassette SAVEs do not include the numeral one.
To SAVE the same program to disk, device number 8, we would type:
SAVE" filename" , 8
Using a numeral four, instead, would send the file to the printer. Logically, we could
even list a program to the screen by SAVE"filename",3, except that the Commodore
64 defines the screen, as well as certain other devices, as "illogical" when used with
certain commands, such as SAVE. However, another command is available in BASIC,
that of "CMO" which will redirect output intended for the screen to another device.
Typing CM04:LlST will cause a program to be listed on the printer instead of the screen,
assuming we have OPENed that device first.
As mentioned, it is usually necessary to open a data "channel" to send information
from one device to another. This is done with the OPEN command.
The particular channel we use is given a number of its own. Which number is assigned
to the data channel is not particularly important. However, a given channel can only
be used to send information to one device at a time. To make the data channels easy
to keep track of, it is often convenient to give them the same number as the device we
are using. So, to open a cassette data file, we might type:
OPEN 1,1,1, "filename"
The first 1 is the number of the data channel or, as it is also called, the "logical file
number." The second 1 is the device number or the cassette tape. The third 1 is referred
to as the "secondary address", an instruction to the computer on what to do with the
data. In this case, "1" means to write the data.
We could just as easily have used:
OPEN 2,1,1, "filename"
This would mean that logical file, or data channel number 2, was being used with
device number 1, to perform task number 1 (write), with the filename within quotes.
However, we will follow the convention of using the same logical file number as the
device number.
What about that secondary address number? What other options are available? For
tape usage, there are two more. We may specify, "0", which signifies reading a file from
the tape, or "2", which will open the channel for writing to the tape, but place a special
"end-of-tape" marker at the end of the fi Ie. In read i ng that fi Ie, the Commodore 64 wi II
progress no further, until the EOT marker is removed.
OPEN just prepares the data channel for us, however. To actually read or write data,
we must use PRINT#or INPUT#, with each followed by the logical file number we are
using.
You may have guessed that SAVE or LOAD are modified forms of the OPEN command, which combine OPEN with PRINT or INPUT in one statement. Since that is true,
the secondary address numbers may be used with them, as well. So, it is possible to enter:
SAVE" filename 11,1,2
This writes the program to device number 1 (the cassette recorder) and places an endof-tape marker after it. The numbers have a slightly different meaning when loading a
program from the tape.
DATA FILES
WHAT IT DOES
Variables
R: Number of items in file
DTA$(n): Array storing data file
FIELD$(n): Field names.
you know your data was recorded successfully? The Commodore 64 uses special circuitry that makes its cassette recorder much more reliable than those used on some other
computer systems. Because of this, it can use much less expensive tapes than other computers. These tapes do have dropouts-places with no iron oxide available to record
information. That is why it is wise to VERIFY any program that is SAVEd.
Because it is so simple to check a program, why not simply store data within a program itself? At the end of the RUN, SAVE the new program, VERI FY it, and you can be
assured that your information is safely transferred to tape.
This subroutine allows you to do that, storing data in the program in the form of DATA
lines. It shows you the lines already entered so that the new one may be placed at the
end. It also prompts you to make one other change, which tells the program how many
items of data have been entered.
Then, in running the program, you can search for an item of data. The Commodore
64 will loop through all the items in the file, display each field, or tell you that the item
is not in the fi Ie.
The program first reads the DATA into a two dimensional string array, DTA$(row,column). Two nested FOR-NEXT loops read all these data into the proper places in the array DTA$(row, column). In line 1060, the first loop starts from 1 to R, which is the number
of rows and which is defined in line 201. Then, the second loop starts, from 1 to 3, the
number of columns. Each time through the second loop, one of the data items is stored
in DTA$(ROW,COLUMN).
When all three have been read for a particular record, the program advances to line
1100. This line sends control back to line 1060 for the next ROW. After all the data
has been read, a menu is presented which offers the choice of adding a listing or retrieving a record. If retrieval is chosen, the user is asked to enter a string to search for. This
string is stored in variable NME$, and a FOR-NEXT loop from 1 to R looks at column
#1 of each row until a match is found.
If so, the data are displayed on separate lines. If no match is found, the computer tells
us the bad news. In either case, the program returns to the main menu. If we want to
add a name, instructions appear telling the user to add the DATA line to the last one
shown and to change line 201 so that R is defined as one larger. The new value of R
(R + 1) is displayed to make this very simple. The program then lists all the lines from
200 to 999 and turns the computer over to the user in command mode.
The program line number chosen should be one larger than the last used (Le., on the
initial RUN, 206 should be used). This will make it possible to fit the maximum number
of OAT A lines to be entered. Actually, the OAT A can be inserted anywhere in the program, but it is much neater if they are located all in one consecutive block.
You Supply
Data and program line changes as prompted by the routine are needed. The first three
DATA items should be the names of your fields, i.e., NAME, ADDRESS, PHONE.
RESULT
Data file is imbedded in the program and can be SAVEd reliably.
10 REM
20 REM
30 REM
**************
*
*
* DATA FILES *
40 REM
50 REM
**************
FIELD$(N): FIELDS
110 REM
120 REM ---------------------------130 REM
NEXT ROW
PRINT CHR$(147)
PRINT "DATA BASE"
PRINT "1. ADD LISTING"
PRINT "2. RETRIEVE"
12BO
1290
1300
1310
1320
1330
1340
1350
1360
1370
13BO
1390
1400
1410
1420
1430
1440
1450
Variables
NI: Number of items in file
DT A$(n): Array storing data file.
You Supply
Your program must furnish data for DTA$(n), either from keyboard entry, or loaded
from some tape or disk file.
The counter NI should be redefined to reflect the number of items in the file each
time an update is made.
You should substitute your fiI~name for "filename" in line 170.
RESULT
Data file written to tape.
REM
REM
REM
REM
*******************
*
*
*
50 REM
60 REM
SEQUENTIAL FILE
WRITE TO TAPE
*
*
*
*******************
++
++
230 REM
Variables
NI: Number of items in file
DT A$(n): Array storing data file
AD: Amount of room beyond number of items in file to allow for expansion.
You Supply
Your program should change the counter NI to reflect the number of items in the file
each time an update is made.
You should subsitute your file name for "filename" in line 160.
RESULT
Data file read from tape.
10
20
30
40
*******************
REM
REM
REM
REM
50 REM
60 REM
*
*
* SEQUENTIAL FILE *
* READ FROM TAPE *
*
*
*******************
230 REM
Variables
NI: Number of items in file
DTA$(n): Array storing data file.
You Supply
Your program must furnish data for DTA$(n), either from keyboard entry or loaded
from some tape or disk file.
The counter NI should be redefined to reflect the number of items in the file each
time an update is made.
You should substitute your filename for "filename" in line 170.
RESULT
Data file written to disk.
10
20
30
40
*******************
REM
REM
REM
REM
50 REM
60 REM
*
* SEQUENTIAL FILE
* WRITE TO DISK
*
*
*
*
*
*******************
***
INITIALIZE
***
140 NI=10
150 DIM DTA$(NI)
160 GOTO 250
170 REM
180
190
200
210
220
230
240 REM
Variables
NI: Number of items in file
DTA$(n): Array storing data file
AD: Amount of room beyond number of items in file to allow for expansion.
You Supply
Your program should change the counter NI, which should be redefined to reflect the
number of items in the file each timean update is made. You should subsitute yourfile
name for "filename" in line 160.
RESULT
Data file read from disk.
*******************
*
*
* SEQUENTIAL FILE *
* READ FROM DISK *
*
*
*******************
++
150 AD= 10
160 GOTO 250
170 REM
180
190
200
210
220
230 NEXT N
240 CLOSE 8: RETURN
240 REM
250
260
270
280
GOSUB 180
FOR N= 1 TO NI
PRINT DTA$(N)
NEXT N
LOAN AMOUNT
WHAT IT DOES
Calculates size of loan, given monthly payment, interest rate, and
length of loan.
Variables
You Supply
You must define these variables:
PAYMENT (the monthly payment desired)
RATE (interest rate in percent, i.e., 10.5 equals 10.5 percent)
NUMBER (number of months loan will run).
The subroutine will return LOAN, or the maximum loan amount given those
parameters.
RESULT
Loan amount calculated.
REM
REM
REM
REM
REM
***************
*
*
* LOAN AMOUNT *
***************
RATE=10
PAYMENT=10
NUMBER = 36
GOTO 250
RATE = RATE/1200
LOAN = PAYMENT*(l-(l +RATE)J\-NUMBER) IRATE
LOAN = INT (LOAN* 100 + .5) 1100
RETURN
PAYMENT AMOUNT
WHAT IT DOES
Calculates monthly payment given interest rate, number of payments,
and loan amount.
Variables
You Supply
You must define these variables:
LOAN (the original amount to be financed)
RATE (interest rate in percent, i.e., 10.5 equals 10.5 percent)
NUMBER (number of months loan will run).
The subroutine will return PAYMENT, which is the monthly payment, against principal
and interest.
RESULT
REM
REM
REM
REM
REM
******************
*
*
* PAYMENT AMOUNT *
*
*
******************
LOAN = 100
RATE=10
NUMBER = 36
GOTO 260
RATE = RATE/100
PAYMENT=LOAN*(RATE/12)/(1-(1+ (RATE/12) ) "-NUMBER)
PAYMENT = INT(PAYMENT*100 + .5) /100
RETURN
NUMBER OF PAYMENTS
WHAT IT DOES
Calculates number of payments given interest rate, monthly payment,
and loan amount.
Variables
RATE: Interest rate
LOAN: Amount of loan
NUMBER: Months of loan.
You Supply
You must define these variables:
LOAN (the original amount to be financed)
RATE (interest rate in percent, i.e., 10.5 equals 10.5 percent)
PAYMENT (the amount of the monthly payment.
The subroutine will return NUMBER, which is the numberof monthly payments that
will be required.
RESULT
Number of loan payments calculated.
10 REM *******************
20 REM *
*
30 REM * NUMBER PAYMENTS *
*
40 REM *
50 REM *******************
60 REM ------------------------------------70 REM
+ + VARIABLES + +
80 REM
RATE:
INTEREST RATE
LOAN:
AMOUNT OF LOAN
90 REM
100 REM
NUMBER: MONTHS OF LOAN
110 REM
PAYMENT: MONTHLY PAYMENT
NUMBER OF WHOLE PAYMENTS
120 REM
WP:
AMOUNT OF FINAL PAYMENT
FP:
130 REM
140 REM
150 REM ---------------------------------160 REM *** INITIALIZE ***
170
180
190
200
LOAN = 1500
RATE=12
PAYMENT = 100
GOTO 280
RATE=RATE/1200
NUMBER=LOG(PAYMENT/(PAYMENT-AMOUNT*RATE)) /LOG(l+RATE)
WP = INT (NUMBER)
FP=PAYMENT*(NUMBER-WP)
RETURN
GOSUB
PRINT
PRINT
PRINT
200
WPj "PAYMENTS OF $ "jPAYMENT
"PLUS FINAL PAYMENT OF"
"$" JFP
Variables
Line By Line DescriptionLines 160 to 190: Define FUTURE, desired future value, the interest RATE in whole
percent per year, and the PERIODS, the number of compounding periods per year. Your
subroutine can substitute INPUT statements to allow the user to enter these figures.
Line 220: Change RATE to decimal figure.
Line 230: Calculate number of years needed to produce the goal value.
lines 240 to 260: Figure number of whole months and years.
Line 290: Access the subroutine.
Lines 300 to 370: Print results.
You Supply
You must define these variables:
FUTURE (desired future value)
RATE (interest rate in percent, i.e., 10.5 equals 10.5 percent)
PERIODS (number of compounding periods per year).
The subroutine will return YEARS, or the number of years that will be required to reach
the desired value.
RESULT
Years calculated.
REM
REM
REM
REM
REM
REM
******************
*
*
* YEARS TO REACH *
* DESIRED VALUE *
*
******************
RATE=10
AMOUNT = 1000
PERIOD = ]65
FUTURE = 2000
GOTO 290
GOSUB
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
220
CHR$(147)
"$" ; AMOUNT; " WILL"
"COMPOUND TO $" ; FUTURE
"IN " ; YEARS; " YEARS
MTHS; " MONTHS"
"AT" jRATE*100j" PERCENT"
"COMPOUNDED "j PERIODS
"TIMES A YEAR. "
COMPOUND INTEREST
WHAT IT DOES
Variables
You Supply
You must define these variables:
AMOUNT (the original amount)
RATE (interest rate in percent, i.e., 10.5 equals 10.5 percent)
YEARS (number of years to be compounded).
The subroutine will return FUTURE, or value of the compounded investment.
RESULT
RATE=10
AMOUNT = 1000
PERIOD=365
YEARS = 10
GO TO 260
RATE=RATE/100
FUTURE = AMOUNT* (1 + RATE/PERIODS) A (PERIODS*YEARS)
FUTURE = INT (FUTURE* 100 + .5) /100
RETURN
GOSUB
PRINT
PRINT
PRINT
PRINT
210
CHR$(147)
"$" ; AMOUNT; " LEFT"
YEARS; " YEARS WILL"
" GROW TO $" ; FUTURE
RATE OF RETURN
WHAT IT DOES
Calculates interest rate, given present and future value, and number
of compounding periods.
Variables
RATE: Interest rate
YEARS: Years compounded
You Supply
You must define these variables:
RESULT
Interest rate calculated.
10 REM
20 REM
30 REM
40 REM
******************
*
* RATE
*
OF RETURN
*
*
*
50 REM ******************
60 REM --------------------------------70 REM
+ + VARIABLES' + +
80 REM
RATE:
INTEREST RATE
90 REM
YEARS:
YEARS COMPOUNDED
100 REM
FUTURE: FUTURE VALUE
110 REM
AMOUNT: AMOUNT TO BE COMPOUNDED
120 REM
YEARS = 10
AMOUNT = 1000
PERIOD = 365
FUTURE = 2000
GOTO 250
GOSUB
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
210
CHR$(147)
"$" ; AMOUNT
"TO PRODUCE $" ; FUTURE
"IN " ; YEARS; "YEARS"
"REQUIRES AN INTEREST"
"RATE OF " iRATE
Variables
A: Dollars and cents amount to be formatted
D$: The dollar figure, formatted.
You Supply
Your program should define A, the dollars-and-cents amount to be formatted. The routine
will return 0$, which is the formatted figure.
RESULT
Dollar amount is properly formatted for display.
10 REM
20 REM
30 REM
*********************
*
*
*
*
40 REM
50 REM *********************
60 REM ---------------------------70 REM
+ + VARIABLES + +
80 REM
A:
DOLLARS AND CENTS
90 REM
AMOUNT TO BE FORMATTED
100 REM
D$: DOLLAR FIGURE
110 REM
120 REM ---------------------------130 REM
140 A=55.345
150 GOTO 330
160 REM
P=2
C=A+5.5*10"-(P+l)
B=INT(C*10"P)/10"P
D$= "$" +STR$(B)
FOR N=l TO LEN(D$)
T$=MID$(D$,N,l)
IF T$= ". " GOTO 270
NEXT N
D$=D$+" .00"
RETURN
L$ = LEFT$ (D$, N)
R$=MID$(D$,N+l)
IF VAL(R$) <10 THEN R$=R$+ "0"
D$=L$+R$
RETURN
TEMPERA11JRE
WHAT IT DOES
Calculates Celsius and Fahrenheit.
Variables
F: Fahrenheit temperature
C: Celsius temperature.
You Supply
You should define a value for either F or C, depending on which way the conversion
will go. This will usually be input from the keyboard.
The alpha character ending the input, either "F" or lie", should be supplied to determine which type of conversion will be activated.
RESULT
Temperature converted to alternate value.
10
20
30
40
50
REM
REM
REM
REM
REM
***************
* TEMPERATURE *
*
*
***************
C=VAL(AN$)
F=INT((9/5)*C+32):RETURN
F=VAL(AN$)
C= INT( (F-32) * (5/90)) : RETURN
PRINT
PRINT" ENTER TEMPERATURE"
PRINT" IN THIS FORM: "
PRINTCHR$(34)i52CjCHR$(34)i" OR II
PRINT CHR$(34) i98FiCHR$(34) i"."
INPUT AN$
A$ = RIGHT$(AN$, 1)
IF A$= "F" OR A$= "C" THEN GOTO 310
PRINT "WRONG FORMAT. "
GO TO 220
IF A$= "F" THEN GOSUB 190
IF A$= "e" THEN GOSUB 170
"i C; "C. II
PRINT F i "F.
DATE FORMATIER
WHAT IT DOES
Formats dates to MM/DDIYY style.
Variables
DTE$: Date
MNTH$: Months
DAY$: Day
YEAR$: Year.
Lines 200 to 220: Enter day of month, which must be at least 1 and less than 31.
Line 230 to 250: Check to see if month should have only 30 days, and force user to
reenter if an illegal date has been entered.
Line 260: Enter year.
Lines 270 to 310: If leap year, then February may have 29 days, otherwise, only 28
allowed.
Line 320: If DAY is less than 10 then add leading "0."
Line 330: Construct MM/DDIYY string.
Line 370: Access the subroutine.
Line 380: Print result.
You Supply
The date to be formatted must be supplied from the keyboard.
RESULT
Properly formatted date.
10 REM
20 REM
30 REM
******************
*
* DATE
*
FORMATTER
*
*
*
40 REM
50 REM ******************
60 GOTO 360
MENU
WHAT IT DOES
Menu template for user programs.
Variables
NC$: Number of choices on menu.
redefine NC. If more than nine choices are listed, you will have to sacrifice single key
entry. Replace line 240 with INPUT A$. Then, any number can be entered.
Note that no menu functions are provided at lines 1000,2000,3000, and 4000; you
must write those routines yourself.
You Supply
Define NC to equal the number of menu choices.
Write subroutines to accomplish your various tasks, using line 270 as a model to direct
control.
RESULT
Operator can select from list of menu choices.
10 REM
20 REM
30 REM
********
*
*
* MENU *
*
*
40 REM
50 REM
********
60 REM
70 Nc=4
80 GOTO 300
90 REM ---------------------------100 REM
VARIABLES
110 REM
NC: NUMBER OF MENU CHOICES
120 REM
++
++
"**
**
PRINT TAB ( 6)
MENU
II
PRINT CHR$(17)iCHR$(17)
PRINT TAB(J) "1. FIRST CHOICE"
PRINT TAB(J) "2. SECOND CHOICE"
PRINT TAB(3) "3. THIRD CHOICE"
PRINT TAB (J) "4. FOURTH CHOICE"
PRINT CHR$(17)
PRINT TAB(6) "ENTER CHOICE"
GET A$: IF A$ = " " GOTO 240
A=VAL(A$)
IF A< lOR A>NC GOTO 240
ON A GOSUB 1000,2000,3000,4000
RETURN
290 REM
300 PRINT
310 GOSUB 150
320 END
***
990 REM
FIRST SUBROUTINE
1000 RETURN
***
1990 REM
2000 RETURN
***
2990 REM
THIRD SUBROUTINE
3000 RETURN
***
3990 REM
4000 RETURN
TIME ADDER
WHAT IT DOES
Variables
You Supply
You must supply start up values for TS, TM, and TH, or else they will default to those
shown in lines 160 to 180. You may change these defaults to zeros if you wish. Your
program should furnish MIN, HOUR, and SEeS values.
RESULT
New total time calculated.
10
20
30
40
50
REM
REM
REM
REM
REM
**************
*
* TIME
*
ADDER
*
*
*
**************
TM=54
TH=40
TS=30
MIN=30
HOUR=2
SECS=30
GO TO 340
TM = TM + MIN*60
TS = TS + SECS
TH = TH + HOUR* 3600
TS=TM+TS+TH
TH= INT(TS/3600)
TS=TS-TH*3600
TM= INT(TS/60)
TS=TS-TM*60
RETURN
GOSUB 340
PRINT CHR$(147)
PRINT "SECONDS: "jTS
PRINT" MINUTES: " j TM
PRINT "HOURS: "jTH
MPG
WHAT IT DOES
Calculates auto miles per gallon.
Variables
BEGN: Starting odometer reading
ODOM: Current odometer reading
GALLNS: Gallons of gas consumed between readings.
You Supply
You need to enter values for BEGN, aDaM, and GALLNS, as outlined above. Variable
MPG will store final miles per gallon figure.
RESULT
MPG calculated.
10 REM *******
20 REM *
*
30 REM * MPG *
*
40 REM *
50 REM *******
60 REM ---------------------------70 REM
+ + VARIABLES + +
80 REM
BEGN:
STARTING ODOMETER
90 REM
ODOM:
CURRENT ODOMETER
100 REM
GALLNS: GALLONS GAS USED
110 REM
120 REM ---------------------------130 REM *** INITIALIZE ***
140
150
160
170
ODOM = 36420
BEGN = 36001
GALLNS = 13 .8
GOTO 230
GOSUB
1SI1
G
OT
~
=
=--=
...,.
rn
:::a
c:
z
E = LEN(MID$(MAIN$, I))
FOR N= I TO E
T$ = MID$(MAIN$, N, 1)
IF T$=CHR$(32) GOTO 1060
NME$ = NME$ + T$
NEXT N
RETURN
Sometimes, after extracting a desired string in this manner, you will want to replace
it with another string of your choice. This is most common in word processing programs,
where a word or phrase will be replaced.
The MID$ = (referred to as "MID$ on the leftofthe equals sign)function permits you
to replace a portion of MAIN$ with SUB$. SUB$ has to be of the same length as the
string it replaces. If you want to insert a LONGER string to replace a SHORTER one,
use another subroutine, INSERT A STRING.
Another statement likely to be valued by those handling text and other strings using
commas (one of several so-called "string delimiters") is the LlNEINPUT feature. Your
user may type in any characters to the INPUT prompt. Keys will be accepted until
RETURN is pressed, as normal. However, the question mark prompt can be changed
to any character of your choice-or omitted entirely.
STRING$ adds a feature to BASIC 2.0 that allows easily building a string of any
size, using a character of your choice. Say you need a string, BALL$, composed
of 20 solid ball graphic characters (CHR$(81)). This subroutine will build it for you
automatically.
MOD is a math-type function that returns the remainder when a number is divided by
another. There are many applications for this feature in games and other programming.
SWAP is a handy way to exchange the values of two variables, even though the SWAP
statement is not included in PET BASIC 2.0. Sorts and other modules that you might design
can use this feature.
LISTER and CHR$ are two modules that handle chores that can also be taken care of quickly
from command mode, just by typing in the command. However, by including either in your
BASIC program with high line numbers, like 30000 and 31000, you can call them at any
time by typing the shorter RUN 30000 or RUN 31000.
MOD FUNCTION
WHAT IT DOES
Simulates MOD function found in other BASICs. Returns remainder
when one number is divided by another.
Variables
MOD: Remainder when NU is divided by DIV
NU: Counter being checked for remainder
DIV: Divisor.
You Supply
You should provide a value for the divisor, DIV, each time it is changed. That is, if you
always want to check to see if the number can be divided evenly by 16, DIV can be
defined once atthe beginning ofthe program. Your counter, NU, should be changed
in value by your program so that it can be checked against FLAG. You may check other
variables simply by making NU equal to them just before calling the subroutine. NU
itself will NOT be altered by the subroutine. For example:
100 NU=C
110 GOSUB
xxx
RESULT
MOD will equal remainder; zero if none.
10 REM
***********
20 REM
30 REM
40 REM
50 REM
*
*
* MODULUS *
*
*
***********
++
++
DIV=)O
NU=NU+l
GOSUB 140
IF MOD = 0 THEN PRINT NU; " EVENLY DIVISIBLE BY" ; DIV
GOTO 180
INSTR FUNCTION
WHAT IT DOES
Simulates INSTR function found in other BASICs. Checks string for
inclusion of shorter substring.
Variables
o.
You Supply
You should supply a value for MAIN$ and SUB$ each time the routine is run. BEGN
will always have a default value of 1, unless you define it as something else just before
calling the subroutine.
RESULT
Position of string searched for will be stored in variable
10 REM
*********
20 REM
30 REM
40 REM
50 REM
*
*
* INSTR *
*
*
*********
SUB$:
100 REM
BEGN:
110 REM
120 REM
130 REM
----0.---------------------------
140 REM
PLACE~_._~
LTH=LEN(SUB$)
FOR PLACE=BEGN TO LEN(MAIN$)
IF MID$(MAIN$, PLACE, LTH) =SUB$ THEN RETURN
NEXT PLACE
PLACE = 0 : BEGN = 1
RETURN
260 REM
270
280
290
300
310
GOSUB 200
IF PLACE = 0 GOTO 310
PRINT fI FOUND AT POSITION fI ; PLACE
END
PRINT flNOT FOUND. fI
REPLACE STRING
WHAT IT DOES
Simulates MI D$ = function found in other BASICs. Replace middle
portion of a string with another string.
Variables
TARGT$: Main string
SUB$:
String to be replaced
Position to put SUB$.
PLACE:
You Supply
Define TARCT$, SUB$, and PLACE just before the subroutine is called.
RESULT
TARGT$ will be changed to include SUBS.
*
*
*
130 REM
140
150
160
170
SUB$ = "TEST"
TARGT$ = "REPLACEMENT MADE"
PLACE=7
GOTO 240
180 REM
190
200
210
220
*
*
*
L$=LEFT$(TARGT$,PLACE)
R$ =MID$(TARGT$,PLACE + LEN(SUB$)
TARGT$ = L$ + SUB$ + R$
RETURN
230 REM
+ 1)
INSERT STRING
WHAT IT DOES
Inserts string into another.
Variables
TARGT$: Main string
SUB$:
String to be inserted into main string
PLACE:
Position to put SUB$.
Like all Commodore 64 strings, neither TARGT$ nor SUB$ can be longer than 255
characters. The resulting string with SUB$ inserted must be shorter than 255 characters
as well.
In the subroutine as written, the target string is "THIS IS THE MAIN STRING OF
CHARACTERS", while the SUB$ is defined as "TEST". Since the PLACE where we want
to insert it is position 7, the new string will read: "THIS IS THE TEST MAIN STRING
OF CHARACTERS".
You Supply
Values for:
The main string TARGT$
The string to be inserted SUB$
The position where it will be put, PLACE.
RESULT
10 REM
20 REM
******************
*
*
40 REM
* INSERT
*
50 REM
******************
30 REM
STRING$
*
*
++
90 REM
100 REM
++
SUB$ :
STRING TO BE INSERTED
PLACE:
110 REM
120 REM ----------------------------
180 REM
190
200
210
220
L$=LEFT$(TARGT$,PLACE)
R$ = MID$ (TARGT$, PLACE + 1)
TARGT$ = L$ + SUB$ + R$
RETURN
230 REM
LISTER
WHAT IT DOES
Simulates LLIST function found in other BASICs. Send program
listings to serial line printer.
Variables
None.
Line 150: Redirect any output normally going to the screen, device #1, to device #4,
the printer.
Line 160: LIST program (sends listing to printer).
Line 170: CLOSE channel, end.
You Supply
If you wish, you may edit line 160 to read LIST 0-29999 so that after the subrouti ne has
been renumbered to 30000 or higher, only the program will be listed.
Or, you can edit the LIST line at any time so that selected lines will be listed to the
lineprinter. Changing the line to LIST 100-500 will cause the lineprinter to print only
those lines, inclusive.
RESULT
Listing sent to line printer.
10
20
30
40
REM
REM
REM
REM
**********
*
*
* LISTER *
50 REM **********
60 GOTO 190
70 REM ---------------------------80 REM
+ + VARIABLES + +
90 REM
NONE
100 REM
110 REM ---------------------------120 GOTO 210
130 REM
140
150
160
170
180
190
CLOSE4
OPEN4,4
CMD4: LIST 230PRINT # 4 : CLOSE4
END
RETURN
200 REM
210 PRINT
220 GOSUB 140
CURS VALUE
WHAT IT DOES
Returns Commodore CHR$ code for any key.
Variables
A: CHR$ value of last key pressed.
You Supply
Just press the key that you want to check.
RESULT
Variable A will equal CHR$ value of that key.
10 REM **************
20 REM *
*
]0 REM * CHR$ VALUE *
40 REM *
*
50 REM **************
60 GOTO 180
70 REM ---------------------------80 REM
+ + VARIABLES + +
A: CHR$ VALUE OF KEY
90 REM
100 REM
110 REM ---------------------------120 GOTO 200
1]0 REM
LINE INPUT
WHAT IT DOES
Simulates LINE INPUT function found in other BASICs.
Allows entering string delimiters into strings.
Variables
AN$: INPUT returned by user
PROMPT$: Prompt character.
Line 170: Only if the key pressed was RETURN, then end the subroutine.
Line 180: Add key pressed to the answer string, AN$.
Line 190: Print the current key pressed to the screen.
Line 200: Go back for another entry.
Line 220: Access the subroutine.
Line 230: Print result, the user entry.
You Supply
PROMPT$ may be redefined as any character you wish.
RESULT
Your finished INPUT will be stored in AN$.
10 REM
20 REM
30 REM
40
50
60
70
**************
*
* LINE
*
INPUT
*
*
*
REM
REM **************
PROMPT$ = "?"
GOTO 220
PRINT PROMPT$;
GET A$: IF A$ = " " GOTO 160
IF A$ CHR$ ( 13) THEN RETURN
AN$ = AN$ + A$
PRINT A$;
GOTO 160
210 REM
SWAP
WHAT IT DOES
Simulates SWAP function found in some other BASICs.
Variables
A$: First variable
B$: Second variable.
You Supply
Values for A$ and B$, or A and B, the two variables which must be swapped.
RESULT
Values exchanged.
10
20
30
40
REM
REM
REM
REM
********
*
* SWAP *
*
*
********
*
50 REM
60 REM ---------------------------70 REM
+ + VARIABLES + +
A$ :
FIRST VARIABLE
80 REM
B$ :
SECOND VARIABLE
90 REM
100 REM
110 REM ---------------------------120 REM
130 A$ = "FIRST"
140 B$ = "SECOND"
150 GOTO 220
160 REM
170
180
190
200
DUMMY$ = A$
A$=B$
B$ DUMMY$
RETURN
210 REM
STRING$
WHAT IT DOES
Simulates STRING$ function found in other BASICs.
Variables
LTH: Desired length
COMP$: Character or string used to assemble finished string
STRNG$: The finished string.
You Supply
Define LTH with the desired number of times the component string wi II be repeated.
If the component string has more than one character, this length will NOT be the same
as the length of the finished string.
Supply a definition for COMP$, which may be either the actual characters or their
CHR$ codes.
RESULT
Variable STRNG$ will be assembled using l TH copies of COMP$.
10
20
30
40
50
REM
REM
REM
REM
REM
***********
* STRING$ *
*
*
***********
180
190
200
210
220
NEXT N
RETURN
230 REM
....
Q
Q
Q
Q
........
....
~
o
o
o
-1---
........g~
....
....
Q
o
o
o
1
o
o
o
o
o.,....
.,....
.,....
PEEK BIT
WHAT IT DOES
Looks at status, 0 or 1, of any selected bit in a given byte.
Variables
ADDRESS: Location to PEEK
BIT: Bit to examine
V: Value of that bit, either 0 or 1.
You Supply
Define:
BIT as the bit
1-8 that you want to examine
ADDRESS as the memory location to be PEEKed.
V will indicate whether the bit is on or off, by equaling either 1 or
RESULT
Status of bit displayed.
o.
************
30 REM
40 REM
50 REM
60 REM
* PEEK
*
BIT
*
*
************
*** INITIALIZE ***
70 ADDRESS 36879
80 BIT=3
90 GOTO 220
100
110
120
130
140
150
REM ---------------------------REM
VARIABLES
REM
ADDRESS: LOCATION TO PEEK
BIT:
BIT TO EXAMINE
REM
V:
VALUE OF BIT
REM
REM
++
++
180 P=BIT-l
190 V= (PEEK(ADDRESS)AND(2 p) )/(2 p)
200 RETURN
210 REM
BIT DISPLAYER
WHAT IT DOES
Variables
ADDRESS: Location to POKE
BIT$: Bit pattern.
You Supply
Define ADDRESS as the memory location, in decimal, that you want to PEEK.
The subroutine returns BIT$, which is a representation of all the bits within that byte.
RESULT
All bits within a byte are displayed.
10 REM
20 REM
30 REM
40 REM
50 REM
60 REM
*****************
*
*
* BIT DISPLAYER *
*
*
*****************
*** INITIALIZE ***
70 ADDRESS = 36879
80 GOTO 260
90 REM ---------------------------100
110
120
130
REM
REM
REM
REM
140 REM
+ + VARIABLES + +
ADDRESS: MEMORY BYTE
TO DISPLAY
BIT$:
BIT PATTERN
BIT$= ""
PRINTTAB( 4) " " ;
FOR N=7 TO 0 STEP-l
V= (PEEK(ADDRESS)AND(2 N)) /(2 N)
G$=MID$(STR$(V) ,2)
BIT$ = BIT$ + G$
NEXT N
RETURN
250 REM
260 PRINT
270 GOSUB 170
280 PRINT" ADDRESS: "; ADDRESS
290 PRINT PEEK(ADDRESS); " = "
300 PRINT TAB(4)BIT$
DITTO ONE
WHAT IT DOES
Soft POKEs any desired bit within a byte so that it now has the value
of one, without changing any other bits.
Variables
ADDRESS: Location to POKE
BIT$: Bit to change to one.
You Supply
Define ADDRESS as the memory location, in decimal, that you want to POKE.
BIT should be given the value of the bit, 1-8, that you want changed to a value of one.
RESULT
Bit within a byte is changed to one.
10 REM
20 REM
30 REM
**************
*
* BIT
*
TO ONE
*
*
*
40 REM
50 REM
**************
60 REM
70 ADDRESS = 36878
80 BIT=3
90 GOTO 200
100
110
120
130
140
REM ---------------------------REM
+ + VARIABLES + +
REM
ADDRESS: LOCATION TO POKE
BIT:
BIT TO CHANGE TO ONE
REM
REM
200 PRINT
210 GOSUB 170
BIT TO ZERO
WHAT IT DOES
Soft POKEs any desired bit within a byte so that it now has the value
of zero, without changing any other bits.
Variables
ADDRESS: Location to POKE
BIT$: Bit to change to zero.
You Supply
Define ADDRESS as the memory location, in decimal, that you want to POKE.
BIT should be given the value of the bit, 1-8, that you want changed to a value of zero.
RESULT
Bit within a byte is changed to zero.
10 REM
20 REM
30 REM
40 REM
50 REM
60 REM
***************
*
* BIT
*
TO ZERO
*
*
*
***************
***
INITIALIZE
***
70 ADDRESS = 36879
80 BIT=3
90 GOTO 200
100
110
120
130
140
REM ---------------------------REM
+ + VARIABLES + +
REM
ADDRESS: LOCATION TO POKE
BIT:
BIT TO CHANGE TO ZERO
REM
REM
160 REM
200 PRINT
210 GOSUB 170
REVERSE BIT
WHAT IT DOES
Soft POKEs any desired bit within a byte so that it now has the
opposite value without changing any other bits.
Variables
ADDRESS: Location to POKE
BIT: Bit to reverse.
You Supply
Define ADDRESS as the memory location, in decimal, that you want to POKE.
BIT should be given the value of the bit, 1-8, that you want changed to reverse in value.
RESULT
Bit within a byte is reversed.
10 REM ***************
20 REM *
*
30 REM * REVERSE BIT *
40 REM *
50 REM
***************
60 REM
***
INITIALIZE
***
70 ADDRESS = 36878
80 BIT=3
90 GOTO 210
100 REM ---------------------------110 REM
+ + VARIABLES + +
ADDRESS: LOCATION TO POKE
120 REM
BIT:
BIT TO REVERSE
130 REM
140 REM
150 REM ---------------------------160 REM
***
***
210 PRINT
220 GOSUB 170
BINARY TO DECIMAL
WHAT IT DOES
Changes binary number to decimal equivalent.
Variables
A$: Binary number in string form
A: Decimal equivalent.
You Supply
Enter the binary number to be converted.
RESULT
Binary number converted to decimal.
10
20
30
40
50
REM
REM
REM
REM
REM
60 REM
******************
*
*
* BINARY/DECIMAL *
*
*
******************
*** INITIALIZE ***
190 REM
200
210
220
230
240
250
260
270
280
290
PRINT CHR$(147)
INPUT "ENTER NUMBER TO CONVERT: "; A$
FOR N= 1 TO LEN(A$)
T$=MID$(A$,N,l)
IF T$ "0" OR T$
"1" GOTO 280
PRINT "NOT BINARY NUMBER"
PRINT CHR$(17)
GOTO 210
GOSUB 150
PRINT A$" = "jA
ROUNDER
WHAT IT DOES
Rounds positive number, and cuts off after desired number
of decimal places.
Variables
A: Number to be rounded
P: Digits desired to right of decimal point
B: Rounded value.
You Supply
You should define A to be the number to be rounded. P will equal the number of digits
to the right of the decimal point that you want. The subroutine will return B, the rounded
value. If B has a fractional decimal part that ends in zero, the zero will not be printed,
even though that many decimal places have been requested. For example, if two decimal
places are desired, 55.344 and 55.399 will be returned as 55.34 and 55.4 respectively.
RESULT
Number rounded as specified.
10 REM ***********
*
20 REM *
30 REM * ROUNDER *
40 REM
50 REM ***********
60 REM -----------------------------70 REM
++ VARIABLES ++
A:
NUMBER TO BE ROUNDED
80 REM
P:
DIGITS DESIRED TO
90 REM
RIGHT OF DECIMAL POINT
100 REM
B:
ROUNDED VALUE
110 REM
120 REM
130 REM ------------------------------
GRfETINGS, DAVID!
'-lOW'S YOUIZ MOM?
II ~ I CC@lTIDllTIDlUllIlililcc@11i:il@Ilil10 @1ITilcrlll
(Q)1i:lh1~If TilJP)10
PROGRAM TRANSFER
WHAT IT DOES
Allows sending program listing out RS232 interface.
Variables
None.
You Supply
Program to upload.
RESULT
Program listing is transmitted out R5-232 interface.
10 REM
20 REM
30 REM
********************
* PROGRAM
TRANSFER
*
*
40 REM
50 REM ********************
60 GOTO 130
LIST
PRINT#2
CLOSE 2
END
TERMINAL
WHAT IT DOES
BASIC terminal program.
Variables
B$: Character sent
C$: Character received.
You Supply
No user changes needed.
RESULT
Dumb terminal communications using BASIC.
*
*
*
120 REM
130
140
150
160
170
180
190
200
210
*
*
*
220 REM
230 PRINT
189
B=O
INPUT A
B=B+A
PRINT B
GO TO 20
You would want to initialize B, as in line 10, each time the subtotal should be eliminated,
and the addition started from zero again.
Jiffie: A %oth second interval used by the Commodore 64 to keep track of elapsed time.
Garbage: Random information with no meaning. Every memory location contains
something. If it is not meaningful information placed there by the computer or user, it
is termed garbage.
Glossary / 191
Merge: To combine two programs in such a way that their line numbers become
mixed. While MERGING may produce interleaved programs, if there are duplicate line
numbers, the program added will write over the same lines in the original program.
Modem: Mod uIator-d emod u lator. A device that converts the Commodore 64's signals
to sounds that can be transmitted over telephone lines. The modem also receives sounds
and converts them back for the Commodore 64 to use.
Monitor: The television-like device used to display video information.
Null modem: An adapter plug or cable that reverses the SEND and RECEIVE lines of
two RS-232 serial interface devices. It enables two computers to be wired directly
together to communicate without one computer's SEND signals being sentto the SEND
lines of the other and RECEIVE trying to RECEIVE from the other.
Nybble: Four bits; half a byte. Often used when a feature has only 16 possible
conditions and, therefore, can be expressed in four bits instead of the full eight in a byte.
The rest of the byte (the other nybble) can be used by the computer for other data registers
or left as random garbage.
Offset: A way of addressing memory through the use of a relative address rather than
an absolute address. If a certain memory block is located between 30000 and 31000,
we can POKE the first location in that block by either of the two methods following:
10 POKE 30000,X
10 OFFSET = 30000
20 POKE OFFSET + 1, X
The second method is often more clear and can also be used when the memory location
defined by OFFSET can vary, as the Commodore 64's color memory changes depending
on the amount of RAM installed.
OR: A Boolean operator that is used to compare one byte with another on a bit for
bit level. If a bit and the corresponding bit in the other byte are either 1, OR will produce a 1 as the result.
Oscillator: An electronic device that, in the Commodore 64, produces a sound when
the proper POKEs are performed to the volume and sound registers.
Parallel: A method of transferring data an entire bit at a time, by sending each of the
eight bits along a separate parallel address line simultaneously. Serial transfer, on the
other hand, transmit each of the eight bits one at a time.
Port: One of the "windows" used by the Commodore 64 to talk to the outside world.
The joysticks send information to the computer through a port.
Prompt: A message to the computer user asking for information. The following INPUT statement includes a prompt.
10 INPUT "ENTER YOUR NAME" ; A$
Pseudo-random: Numbers which appear to be random but which are actually taken
from a very long list of numbers. The Iist is so long that ittakes a great deal of time before
it repeats, and since the computer usually starts at a different position in the list each
time, the series seems to be different.
Random access: A method of getting data, either from memory or from disk, which
allows going directly to the information required and using it, without accessing any
of the other information in the file or memory.
Real-time clock: The built-in clock in the Commodore 64 that keeps track of elapsed
time since the computer was turned on or since the clock was last reset by the user.
Register: A location storing a status of some type. Some types of registers are located
in the Commodore 64's microprocessor and can be accessed only through machine
language. Some memory locations in the Commodore 64 perform a register-like function, telling the computer whether a certain feature is ON or OFF, or the volume of a
sound oscillator, or some other status.
Rheostat: A variable resistor, like those used in paddles, which lets more electricity
flow when turned one way and less when turned the other.
R5-232: A serial interface device that allows the Commodore 64 to communicate with
devices like printers or modems one bit at a time.
Sequential: A serial file access method in which each piece of information is stored
after another and must be written or accessed in that fashion.
Serial: Sequential data storage or transfer.
String delimiter: A character that the computer recognizes as the "end" of a given
string input. The most common are commas and quotation marks.
String variable: A variable that can store alpha information only. Strings can include
numbers, punctuation marks, and graphics, but the computer recognizes them only as
characters, not as values.
Subroutine: A program module that performs a specific task, called through the
GOSUB statement, and ending with RETURN, which directs program control back to
the instruction following the GOSUB.
Toggle: A feature that can be either ON or OFF is sometimes "toggled" between the
two, like a lightswitch.
Upload: To store a file from disk or tape in the Commodore 64's memory buffer and
then send it through telecommunications to another computer, which can then write
it to tape or disk for permanent storage (downloading.)
Voice: Oneoffouroscillators in the Commodore 64 that produce sounds. Three have
overlapping music ranges, while the fourth voice produces "noise."
envelope, 38
BASIC tricks, 77
baud, 185, 186
binary, 60, 65, 66, 179
bit, 59, 60, 66, 170, 171, 172, 173,
174, 175, 176, 177, 178
Bits and Bytes, 169
Boolean, 59, 170
Business and Financial Subroutines,
123
G
Game Routines, 93
I
integer, 181
channel, 109
character sets, 56, 65, 66, 94
character memory, 10, 59, 17, 20
communications, 184, 185
Communications and Other Tips,
183
controller, 1 3
jiffie, 26, 29
joystick, 8, 9,11,14,16,17,18,
20,59
M
menu, 9,42, 124
merging, 2, 3,4
Merging Subroutines, 1
modem, 184, 185
D
data files, 108,110,111,112,114,
116,117,119
default, 156
disk, 56, 73,89, 108, 110, 112,
117,118,119
N
NOT, 59, 170, 173
nybble,59
193
o
Other Commodore 64 Tricks, 55
OR, 59, 170, 173
p
paddle, 13
pseudorandom, 97
R
random, 45, 46, 94, 95, 99, 110,
124
real-time clock, 26, 29, 30
register, 10, 38, 39, 40, 41, 45, 48,
50, 171
ROM, 65, 66
S
screen memory, 10, 59, 17,20
sector, 108
sequential, 108, 115, 117
sort, 78, 82, 83, 84
sound, 20, 38, 39,40,41,43,45,
48, 101
T
TI,TI$, 26, 27, 29, 30, 32,89
toggle, 170
U
Using Joysticks, 7
Using the Clock, 25
Using Sound, 37
utility, 2
W
wavefurm, 38,43,45,48, 50
CONTENTS
Merg ing Subroutines With Your Program s/Using Joysticks / Using Th e Clock / Using
Sound / O ther:e:ommodore 64 Tri cks/ BASIC Tri cks/Game Routines/ Data Files/ Business
And FinanCial Subrouti nes / Add New Functions To Commodore BASIC/ Bits And Bytesl
~9JWl~.a ti ons And Other Tips/G:;lossaryllndex
ISBN 0-89303-383 - 9