You are on page 1of 516



Copyright c Peter Lupton and Frazer Robinson 1984

All rights reserved

First published in Great Britain in 1985
by Century Communications Ltd,
12 - 13 Greek Street,
London Wl V 5LE

ISBN 0 7126 06769

Printed in Great Britain in 1984 by
Billing & Sons Limited, Worcester.

Typeset by Spokesman, Bracknell


The programs in this book have been typeset
directly from the Commodore 64.



Computers and Pro grams
Setting up your 64
First Steps
Pro gram Control
Data and Pro grams
Pieces ofStrlngs
Logical Thinking
Memory Management
Sound and Music - Part 1
Character Graphics
High Resolution Graphics
Permanent Storage
Advanced Techniques




BASIC and how i t works
Machine code on the 64
Bit-Mapped Graphics - Part 1
Bit-Mapped Graphics - Part 2
Display Interrupts
Pro grams and People
Sound and Music - Part 2
The 1541 Disk Drive
Advanced Disk Operations
The MPS801 Printer



BASIC Commands
BASIC Tokens and Abbreviations
Summary of DOS Commands
BASIC Error Messages
DOS Error Messages
Speeding U p Programs
Colour Codes
Musical Notation
N umbering Systems
Kernal Routines
The 6510 Instruction Set



SID Registers
VlC TI Registers
Screen Memory Maps
Character Codes
System Memory Map
Graphics Loader Pro grams


It is customary at this point to mention all those
people without whose help this book would not
have been possible. We would like to
acknowledge the support and enthusiasm of Peter
Rhodes without whom none of our books would
have been possible. We haven't been able to say
so until now - Thanks Peter!

This book is an omnibus edi tion of our two books,

The Commodore 64 Handbook
The Advanced Commodore 64 Handbook
We have taken the opportunity to correct one or
two errors which crept into the first editions, and to
clarify some obscurities noticed by our readers.
The combined volumes form a complete guide to
the Commodore 64.
The first section of this book provides a complete
introduction to BASIC and the features of the 64,
while the second introduces machine code
(providing a set of routines to speed up graphics)
and describes the use of disk drives and printers.
With this book at your side you will be fully armed
for the great adventure of64 programming!

Peter Lupton and Frazer Robinson 1984



and so the set of instructions is often said to form a programming language. These lists of instructions are called programs. similar to an electronic calculator. are not as good at understanding languages as people are. and most of this book is concerned with how these programs are written. but with more sophisticated display and memory facilities. The feature that gives computers their immense flexibility and potential is this: they can store lists of instructions which they can read through and obey at very high speed. A computer is at heart little more than a high-speed adding machine. for all their power. a computer is not really intelligent at all. There are many different computer programming languages. The rules for wri ting pro grams resemble the rules of a spoken language. The computer instructions which form programs must follow certain rules. (The name BASIC is an acronym for Beginners' All-purpose Symbolic Instruction Code. or the computer will not be able to understand them.CHAPTER 1 COMPUTERS AND PROGRAMS Despite everything you may have heard about computers being hyperintelligent machines which are on the point of taking over the world. the one that the Commodore 64 understands (in common with most other personal computers) is called BASIC. The BASIC language used by the 64 .) A programming language is much simpler than a human language because computers.

the tgrammar' of the language . remember this. and it is possible to write programs to perform very complex tasks. These may seem like limitations. The rules for combining the words .2 The Commodore 64 Omnibus . again because it is difficult to make computers that can use languages in the relaxed sort of way in which we speak English. so whatever happens. Finally.Part 1 has less than 80 words. but in fact as you will discover BASIC is still a powerful language. The 64 won't take over the world unless you make i t! . you're the boss.are much more strict than for a language like English. Your computer will not do anything unless you tell it to.

. . The diagrams above show all the connector sockets ofthe 64. To t I " I I I + + Cassette Interface User Port I \ \ I Cartridge Socket Tuning Screw TV Lead Audio & Monitor Senal Interface \ \ The Commodore 64 Connectors .CHAPTER 2 SETTING UP YOUR 64 Before you can use your Commodore 64 you must connect it to apower supply and to a television.Rear View ~.Side View load and save pro grams you will also need to connect a cassette unit to the 64. Before connecting anything. Power Socket The Commodore 64 Connectors .~ L/ r Joystick Sockets I On/Off Switch .. make sure you know what should plug in where.

The lead has a different type ofplug at each end. The socket for the power supply is at the righthand side ofthe machine.Part 1 There are several sockets through which the 64 passes and receives information. so take care that you don't try to force in the wrong one. and for this almost any TV will do. CASSETTE RECORDER The Commodore 64. You cannot use an ordinary cassette recorder wi th the 64: you must use the special Commodore . and plug the other end into the socket at the back ofthe computer (check the diagram). Plug this power supply into the mains. so that you don't have to type them in every time you need them.4 The Commodore 64 Omnibus . plug the supplied aerial lead into the aerial socket of the TV. the colour displays produced by the computer will appear as shades of grey. Do not switch on yet! DISPLAY The Commodore 64 uses a standard domestic TV to communicate with you. use a modern. and this is obtained from the power supply unit supplied with your computer. and one through which it gets the electrical power it needs to operate. good quality colour TV. uses cassette tapes to save programs or information. so be sure ~o refer to the diagram be fore plugging anything In. and plug the output lead into the computer. To connect the 64 to the TV. like most other small computers. To get the best results. POWER The 64 needs a low voltage DC supply. Ifyou use a black and white set. The sockets are not alliabelled.

DISKDRIVE Pro grams can also be stored on floppy disks. PRINTER If you have a printer. The cassette unit plugs into a socket at the rear of the computer. or there is a risk of damaging the computer. (It is also much more expensive). If you are also using a disk drive you should plug the printer lead into the spare socket at the rear of the disk drive.) Last. switch on the computer itself. The equipment must be switched on in the right order. switch on the disk drive and then the printer. The disk drive connects to the round serial interface socket at the rear of the computer. SWITCHING ON When you have connected everything together. No separate power supply is needed for the cassette unit as this is provided by the computer. you are ready to switch on. (Remember that you should never switch a disk unit on or offwith disks inside it. The disk unit requires its own power supply and so must also be plugged into the mains. The printer also has aseparate mains lead. . A floppy disk drive is faster than a cassette unit and is more flexible in use. First swi tch on the TV. Second.Setting up your 64 5 cassette unit. which is available at extra cost. its lead plugs into the serial interface socket at the rear of the computer.

use aspare channel and keep tuning until you see this appear on the screen: **** COMMODORE 64 BASIC V2 **** 64K RAM SYSTEM 38911 BASIC BYTES FREE READY. tune to channel 36. then the disk drive and printer. . perform the following checks: 1 Check that the aerial lead is connected. 3 Try tuning the TV again.if possible try a different TV.6 The Commodore 64 Omnibus . If you are unable to tune the television. or. The red power indicator should be on. TUNING To get a display to appear on the TV screen. and . and last of all the TV. on a pushbutton set. 2 Make sure the computer is connected to the mains and switched on.Part 1 Switching off should be carried out in the reverse order: first the computer.

and contains no circuitry for TV reception. a good colour monitor can cost twice the price ofthe computer! The 64 provides a standard output for a monitor. you could buy a monitor. consult your dealer.Setting up yauf 64 7 With a little time and careful tuning. Ifyou are unsuccessful. However. . as certain types of TV seem to give better results than others. it's worthwhile taking the computer to the shop. through the socket next to the cassette recorder socket. For the best quality display. If you are thinking of buying a TV especially for use with your 64. Your dealer can advise you on the connecting leads required. This is a display specifically designed for use with a computer. it is possible to get a clear and stable display on nearly all types ofTV.

(If instead of printing 'CBM 64' the computer prints '?SYNTAX ERROR' or 0.will move to indicate where the next letter you type will appear. You give instructions using the keyboard. it means you have made a typing mistake. The words 'CBM 64' appear on the screen. The flashing square . and you must be able to find out how it responds to them. Type the following phrase on the keyboard: PRINT "CBM 64" You will see the letters appear on the screen as you type them. TryagainD. and the 64 displays its response on the TV screen. N ow press the RETURN key. and the word 'Ready' is printed to tell you that the 64 is waiting for your next command. Try another command: PRINT "HELLO!" . Communication is a two-way process: you must give the 64 instructions. So. to give the 64 a direct command you type it at the keyboard and press RETURN. Nothing else happens though the computer has not yet obeyed your instruction.CHAPTER 3 FIRST STEPS Before you can make use of your Commodore 64. you must find out how to communicate with it.called the cursor .

When it reaches one side it re-appears at the other side. Try making it print yourname. This method of assigning two functions to a key is exact1y the same as on a typewriter. (it will continue to move for as long as you press the key) and watch what happens when it gets to the edge of the screen. the display begins to move off . You can tell the 64 to print any sequence of letters. the letters between the quotation marks are printed. but you must remember to put them between quotation marks. Try moving the cursor around.First Steps 9 Again. with one key meaning three or four different things depending upon which other key you press as weH. The Cursor The cursor can be moved around the screen using the two keys labelled 'CRSR' at the bottom right of the keyboard. To reverse the direction. You don't have to type PRINT in fuH every time the question mark means the same to the computer. But when the cursor reaches the bottom of the screen. Try: ? "HELLO! 11 (remembering to press RETURN. there are a number ofdifferent ways to alter the display. of course). MANAGING THE DISPLAY As weH as typing on to the screen. Keep one or other of the keys pressed to move the cursor in the direction of the arrows at the front of the key. it is taken a stage further. except that on the Commodore 64. hold down the SHIFT key while pressing the cursor key.

To return the cursor to the top left hand corner of the screen (known as the HOME position). Clearing the screen This can be done in two ways. press the CLRlHOME key. For example. Notice that anything that disappears when the picture scrolls cannot be recovered. if you type: PRONT "CBM 64" and then realise your mistake.before you press RETURN . use the INST/DEL key which will delete characters to the left of the cursor for as long as it is held down.there's no need to move the cursor to the end of the line. To remove large amoun ts of text. To insert text in a line. You can now press RETURN . Corrections If you notice . This means you must be careful to delete any rubbish from the line before pressing RETURN. and type an I.Part 1 the top of the screen.this will create aspace for your addi tions.that you have made a typing mistake . hold down the SHIFT key and press the INST/DEL key . you can correct the error by using the cursor keys. This is a general rule for the 64.10 The Commodore 64 Omnibus . position the cursor over the offending 0 using the cursor keys. You can hold down the SHIFT key and press the CLR/HOME key. pressing RETURN will tell the computer to consider the line upon which the cursor rests as a command. . This vertical movement is called scrolling.

Try: PRINT 5 (RETURN) You can do arithmetic.First Steps 11 Alternatively. NUMBERS As weIl as printing words. Addition: PRINT 5+3 Subtraction: PRINT 7-4 Multiplication: PRINT 3*5 Division: PRINT 15/6 Powers (exponentiation): PRINT 3 i 2 You can ask the 64 to calculate longer expressions. such as: PRINT 3*5 + (5-3)/(2+1) * 7/8 . the Commodore 64 can also handle numbers. hold down the RUN/STOP key and press the RESTORE key to clear the screen. return the screenlborder colours to dark blue/light blue and display the READY message.

the computer follows strict rules about the order in which the various arithmetical operations are performed. Try the following examples.Part 1 In working out expressions like this.12 The Commodore 64 Omnibus . hold down the CTRL key and press one of the numeric keys . If you are unsure. Second Any powers (squares. Third The 64 performs the multiplications and divisions. You can change the colour of the characters at any time . Now type some characters . and see ifyou can work out the answers yourselfto check that you know what the computer is doing. cubes. To change the colour of the characters.these will appear in the same colour as the cursor. First The expressions inside brackets are evaluated. the cursor will change to the colour written on the front ofthe key. as can the colour of the characters displayed on the screen. Fourth The additions and subtractions are performed. etc.4 4 t 3 / * 2 2 COLOUR The colour of the screen display and its border can be changed to be any one of 16 colours. put brackets round the bit you want calculated first. PRINT PRINT PRINT PRINT PRINT 2 * 2 + 2 + 2 * 6 + 3 / 3 t 2 + (3 + 4) 2 * 2 2 + 2 5.) indicated by t are worked out.

To obtain a further eight. the code for yellow.2 (and press RETURN) If you typed correct1y. by using a BASIC command. so the border turns red. The keys 1 to 8.7 This turns the screen yellow because 7. You can also change the colour of the screen: POKE 53281. The POKE command will be explained more fully later on. clear the screen (press SHIFT and CLRJHOME) and type: POKE 53280. Don't worry ifyou can't follow what is happeningall will be made clear later. The colours obtained with the various keys are shown in Appendix 5. 2 is the code for red. hold down the CBM logo key (at the bottom left hand corner of the keyboard) and press one of the number keys.First Steps 13 by holding down the CTRL key and pressing one of the number keys again. the border will change from light blue to red. The colour of the screen and border can be made to take on any one of these colours. for now it is enough to know that it puts a number (in this case 2) into a special area of memory which the 64 uses to determine the border colour. To see this happen. has been placed in the area of memory which the 64 uses to determine screen colour. since we will make great use of the POKE command throughout this book. in conjunction wi th the CTRL key will give eight colours. .

PRINT "THIS IS A TEST" will print the message 'TH1S 1S A TEST'. hold down the CBM logo key and press the SH1FT key .instructions to the 64 must all be in the same case. When you first switch on and type.14 The Commodore 64 Omnibus . PRInt "STILL TESTING" will not work . Thus: print "this is a test" still works because the 64 understands both types oftext. Now. or upper case. . all the letters on the screen are displayed as capitals.Part 1 RETURNING TO NORMAL If at any time you want to return to the dark blue/light blue screenlborder combination. as do any subsequently typed letters.all the letters on the screen turn into lower case. The 64 can also display text in lower case. However. simply hold down the RUN/STOP key and press the RESTORE key. TEXT There are two other things you can do which alter the appearance ofthe display.

These can also be displayed on the screen by holding down the CBM key or the SHIFT key together with the appropriate key. hold down CTRL and press the 0 key (RVS OFF) or press RETURN. all our characters have been in light blue on a dark blue background. using the SHIFT key instead selects the right hand character. with dark characters on a light background. Pressing a key in conjunction with the CBM key will display the left hand graphics character. MULTIPLE COMMANDS You can put more than one instruction in one command if you separate the instructions with colons (:). anything you type on that line appears reversed. Try this: (see also the note which follows the examples) PRINT "{CLS}":PRINT "3+4="3+4 :PRINT Or this: . To try this hold down the CTRL key and press the 9 key (note that the words RVS ON are written on the front of the key). GRAPHICS CHARACTERS You will notice that displayed on the front ofmany of the keys are two symbols or graphie characters. From now on.First Steps 15 REVERSE MODE Up to now. To turn this off. since reverse video is active only for one line at a time. The 64 allows you to display reversed text.

followed by a quotation mark. followed by a further quotation mark. which teIls the 64 to clear the screen.16 The Commodore 64 Omnibus . Similarly. "{ GRN}" means hold down the SHIFT key and press 6. The screen will display a reverse heart character within the quotation marks. . for example: PRINT "{CLS}" means type PRINT .5 :PRINT "{GRN}LURID COLOUR SCHEME!!" It doesn't matter if you run over the end of the line on the screen. then hold down the SHIFT key and press CLRlHOME. In the next chapter we will discover a way of giving the computer a very large number of instructions all at once . though most should be obvious. This method of indicating certain key presses is used throughout this book and a full list of the abbreviations is given in Appendix 1. the characters within the 'curly' brackets { } indicate which key to press when typing in the listing .8:POKE 53281.they should not be typed. as long as there are no more than two screen lines of characters (including the spaces) in the command. Entering a number of instructions together like this can get very cumbersome. to set Green.the PROGRAM.Part 1 PRINT "{CLS}":POKE 53280. Note In the two examples above.

its border and the characters on the screen can be set to any one of16 colours. PRINT 3+4 prints the result ofthe sumo These can be combined: PRINT "3+4*5+7 = " 3+4*5+7 COLOURS The colour of the screen.First Steps 17 SUMMARY PRINT instructs the 64 to print something on the screen. MULTIPLE COMMANDS Anumberofseparate instructions may be included on one line but must be separated by colons (:). PRINT "ABCDEFG" prints the characters between the quotation marks. .

we saw that it is possible to give the computer a number of instructions at one time by wri ting them one after another on one line.CHAPTER 4 PROGRAMMING At the end ofChapter 3. and that the 'READY' message does not appear after you press RETURN. type each line in turn (remembering to press RETURN after each).using a program. We will now look at a much more powerful way of doing this . You will see that the 64 does not obey the instructions as they are entered.5 PRINT"{GRN}LURID COLOUR SCHEMEl" To enter the pro gram into the computer. In Chapter 3 we had: PRINT"{CLS}":POKE 53280.5:PRINT"{GRN}LURID COLOUR SCHEME" Rewri tten as a pro gram i t looks like this: 10 20 30 40 PRINT "{CLS}" POKE 53280.8 POKE 53281. The computer recognises that each li ne .8:POKE 53281. A computer program is a numbered list of computer instructions which are entered together and stored by the computer to be obeyed later. Let's look at the last example of Chapter 3 and see how we can turn it into a program.

you can inspect the stored program by typing LIST (and pressing RETURN. For example: LIST 30-50 lists allIines from 30 to 50 LIST 20 lists only line 20 LIST . of course).30 lists all lines up to and including Une 30 LIST lists all lines from Une 30 to the end of the pro gram 30- If a program is very long. Type this in (followed by RETURN).) . and correct the mistake. and the 64 prints a message such as 'SYNTAX ERROR IN LINE 20'. and the program is stored for future use.Programming 19 is part of a program. To order the computer to act on the program you use another BASIC command: RUN. So the screen scrolls to display the program and this can be slowed by holding down the CTRL key during LISTing. there is a typing mistake in that line and the 64 cannot understand the instruction. because each be gins with a number. When you have typed in all the lines. (lf it doesn't. LIST the line. You will see that the program gives exact1y the same results as the multiple instructions in Chapter 3. it will occupy more lines than there is space for on one screen. The instructions are listed in numericalorder on the screen. You can list parts of the program by specifying line numbers. This teIls the computer to read through the stored program and obey each instruction in order.

is ignored. Ifyou enter: 30 POKE 53281. For example RUN 20 begins executing the program at line 20.2 the originalline 30 is replaced by the new one. type the line number and press RETURN. and line 10.) Extra lines are added by typing them as before: 35 PRINT IIAN EXTRA LINE II Notice that the computer inserts the extra line in the appropriate place: it is not put at the end. NOTE It is a good idea always to number program lines in steps of 10 to allow extra or forgotten lines to be inserted without having to renumber the whole program. It is possible to begin execution of a program from a line other than the first by specifying the line number. . and the next time you RUN the pro gram the screen will turn red instead of green. It will be stored in the computer's memory until you swi tch i toff.The Commodore 64 Omnibus . (To return to the original screen colours. Pro grams can be alte red or added to at will. the instruction which clears the screen.Part 1 20 A pro gram may be RUN as many times as you like. hold down the RUN/STOP key and press RESTORE. To alter an instruction. retype the line. To delete a line. The line is deleted from the list in the computer's memory.

Programming 21 Now see if you can alter the example program to PRINT different words on the screen and in different colours.245 POKE 54276. You will then be ready for the next program.0) .33 FOR L=O TO 15 GOSUB 500 FOR P=O TO 200:NEXT P POKE 54276.J) NEXT J.83 POKE 54277.NO(Z. When you have exhausted the possibilities of this program.1) DEF FNA(X)=INT(RND(1)*16) FOR Z=O TO 4 FOR J=O TO 1 READ NO(Z.33 W=W-50 NEXT L GOSUB 500:GOTO 300 FOR Z=O TO 4 POKE 54273.15 POKE 54278.Z PRINT CHR$(147) POKE 54296. RUN it and wait for a te lose Encounter'! 10 20 30 40 50 60 70 100 110 120 130 200 210 220 230 240 250 260 270 300 500 510 W=850:DIM NO(4.32 FOR P=O TO 400:NEXT P POKE 54276. you can use the command NEW to delete the whole program. CLOSE ENCOUNTERS Here is a more interesting program for you to try it mayaIso be useful if you're in the habit of attempting to communicate with aliens! Don't worry if you don't understand all the instructions you will do when you've read the rest of the bookjust type it in.

8.The Commodore 64 Omnibus . you may stop the program by holding down the RESTORE key and pressing the RUN/STOP key.B POKE 53281. .Part 1 22 520 530 540 550 560 570 580 590 600 610 POKE 54272.VARIABLES We discovered in Chapter 3 that the 64 will print the answers to arithmetical problems in response to commands such as: PRINT 3+5 This sort of instruction can be included In a pro gram like this: 10 20 PRINT"{CLS}" PRINT "3+5 = " 3+5 but it would be difficult to make much use of this for working out your personal finances. If the program stops and the message t? SYNTAX ERROR IN LINE xxx' is printed. If any other error message is printed.1) B=FNA{X) S=FNA{X) POKE 53280.143 Check the pro gram carefully for typing errors. it means you have made a typing mistake in that line.209. check the whole of the program for mistakes. If you do not succeed in making contact with any aliens.21.12. and then RUN i t. ARITHMETIC IN PROGRAMS .NO{Z.S FOR p=o TO W:NEXT P NEXT Z RETURN DATA DATA195.

4 ... will print the area of a rectangle 12 inches by 8 inches. The area of a rectangle is equal to the width of the rectangle multiplied by the height. when RUN.... These number-names are called VARIABLES because they represent varying numbers..Programming 23 What gives a computer the power to perform complex data processing (or ~number crunching') tasks is its ability to do algebra: to use names as symbols for numbers. r HEIGHT AREA = WIDTH x HEIGHT 1__________ . By changing the numbers in lines 10 and 20 we can obtain the area of a rectangle of any size... This me ans that pro grams can be written with names to symbolise numbers.. . By using names instead of numbers we can write a program to work out the area of any rectangle. For example: 10 20 30 40 WIDTH = 8 HEIGHT = 12 AREA = WIDTH * HEIGHT PRINT "AREA = 11 AREA This program.. and then RUN with different numbers attached to the names..WIDTH .. .. Let's try an example..

your pro gram will not run.Part 1 VARIABLE NAM ES Any number of letters can be used in a variable name. and BREADTH contains READ. There must not be any spaces in a variables name: this will confuse the computer. you cannot use the BASIC reserved variables TI. both of which are BASIC words. E7. for example Al. TI$ and ST. the rest are ignored. LI. For example. that ifyou use these names: FR FRUIT FRIEDEGG the computer will treat them as the same variable. This me ans. NOTE You cannot use as a variable name any of the BASIC command words. but the other characters may be numbers. All variable names must begin with a letter. (See Appendix 2 for a full list of all the BASIC reserved words. LENGTH contains LEN. but only the first two characters of the name are considered by the 64. but will give SYNTAX ERROR messages whenever the name is used. or any name which includes a command word. Similarly.24 The Commodore 64 Omnibus . whch are reserved for use by the 64's internaioperations. for example. Ifyou do. FR.) .

the type representing words are called String variables because they contain sequences or tstrings' of characters.Programming 25 TYPES OF VARIABLE There are three different types of variable.72 SIZE = 87.3 * 2. Here are some examples: . a program which kept arecord ofthe number of chocolate bars in stock at a shop could use integer variables to count them. Integer variables must be identified by the % sign after the variable name. Real variables should be used in all arithmetical programs. REAL VARIABLES These are used to represent numbers and can have any value. two of which represent numbers. the third representing words. not fractions. Real variables can have any value.5 INTEGER VARIABLES These can only represent whole numbers (or integers). ~ut the takings of the shop would have to be stored In real variables. The types which represent numbers are Real and Integer variables. as in CHOCBARS%. For example. For example: REAL = 3. or fractions of pounds (Le. pennies) would be ignored. The variables in the previous program are real variables. They may be used when counting events or objects. whole numbers or fractions. or to store constant integer values.

76 NAME % = 3 NAME $ = "GEORGE WASHINGTON" The computer will not be confused. so be careful! .The Commodore 64 Omnibus . The variable name for astring variable must be followed by a dollar sign ($) to distinguish it from the other types ofvariable. Examples are: NAME$ = "WINSTON CHURCHILL" STRING$ = "ABCDEFG" Note that the letters defining the variable contents are enclosed by quotation marks. butyou might. The maximum number of characters astring variable can hold is 255.5 PRINT NUMBER% will print the value 7. such as: NAME = 87. Ifyou try to make astring Ion ger than that the 64 will display the message (STRINGTOO LONG ERROR'. So 10 20 NUMBER% = 7. NOTE It is possible to have variables of different types with the same name.Part 1 26 NUMBER% = 3+6 COUNT % = COUNT% + 1 CHOCBARS% = 1000000 If you try to give an integer variable a fractional value only the whole number part is stored. STRING VARIABLES Astring variable is used to store words or letters or numbers.

In normal use a variable name represents one stored number or string. The array would be used like this: 10 20 30 40 50 NAME$(O) NAME$(l) NAME$(2) NAME$(3) NAME$(4) = = = = = "LUCY" "JULIE" "8HEILA" "NICK" "BRIAN" . Here is a diagram of an array which uses one reference number.27 Programming ARRAYS Each of the three types of BASIC variable . An array can be pictured as a collection of boxes. REFERENCE NUMBER CONTENTS 0 LUCY 1 JULIE 2 SHEILA 3 NICK 4 BRIAN 5 SUE ArrayNAME$ The array is astring array and has 6 elements numbered from 0 to 5.real.may be used in the form of what is called an Array. with one or more reference numbers identifying the individual items. In an array. integer and string . the variable name represents a collection of stored information.

and by the other variables of the program. You can use arrays with more than two dimensions. but this depends on how much memory is occupied by the pro gram i tself. this time laid out in a grid as shown opposi te.O) = "FLORENCE" P$(O.B): " " .l) = "WASHINGTON" P$(2.The Commodore 64 Omnibus . NAME$(N) NEXT N ° As mentioned before. . but you will find the 64's memory will not hold arrays ofmore than about four dimensions (the exact number depends on the number of elements in each dimension).Part 1 28 60 100 110 120 NAME$(5) = "SUE" FOR N = TO 5 PRlNT N.O) = "GEORGE" P$(l. an array may have more than one reference number.1) = "NEWTON" FOR A = TO 2 FOR B = TO 1 PRlNT P$(A. NEXT B PRlNT NEXT A ° .l) = "NlGHTlNGALE" P$(l.2) P$(O. The number of reference numbers per item is called the number of dimensions ofthe array.0) = "lSAAC" P$(2. Here again the array can be though t of as a collection of storage boxes. The maximum allowed value of each reference number may be anything up to several thousand. Here is a pro gram using an array with two reference numbers per item: 10 20 30 40 50 60 70 100 110 120 130 140 150 OlM P$(2.

The computer waits for you to type in a number or letter string. When the computer finds an INPUT statement in a program. GETTING VALUES INTO PROGRAMS It would be very inconvenient to have to alter a program to make it handle different numbers. Type NEW (RETURN) to delete any program currently in the computer's memory and then try the example overleaf: . a question mark is displayed on the screen. You do not need a DIM command if you are using onedimensional arrays with no more than eleven elements numbered from 0 to 10. so there are a number of instructions which allow numbers or letters to be given to a prcgr~-n while it is running. The first ofthese is INPUT.29 Programming B = 0 B = 1 A=O FlORENCE NIGHTINGALE A = 1 GEORGE WASHINGTON A=2 ISAAC NEWTON Array P$ A DIM command must be included at the beginning of any program which will use arrays of more than one dimension. which it will then store as a variable before continuing with the rest of the program. The command teIls the computer to reserve memory space for the array. as the 64 is able to handle these automatically. or with more than eleven elements (0-10).

Pressing RETURN enters a null string but this time nothing is displayed. if you specify astring variable in the INPUT command: 10 20 INPUT NAME$ PRINT NAME$ This program will accept both numbers and letters and store them as astring variable. NOTE If you typed anything other than a number the computer would print the message 'REDO FROM START'. This is because the variable NUMBER is a real variable and can only store numbers. Type a number and press RETURN: the n umber is prin ted. Ifyou press RETURN without typing anything. and there must always be a . but it must be contained within quotation marks. the variable is unchanged. You can use any message you like. It would then display another question mark and wait for you to type the number in again. Messages can be printed be fore the question mark to tell the person using the program what to type in. so in this case a zero is displayed. The INPUT instruction can handle strings too. NAME$ and RUN the program again. Change line 10 to: 10 INPUT IITYPE A WORD II .30 The Commodore 64 Omnibus .Part 1 10 20 INPUT NUMBER PRINT NUMBER When you RUN this program you will see a question mark on the screen.

If you enter too many items the surplus ones will be ignored and the 64 will print (?EXTRA IGNORED'. 10 20 30 INPUT "NAME. U sing INPUT has made the program much more flexible: we don't have to alter the program to use different numbers. 10 20 30 40 50 60 REM IMPROVED AREA PROGRAM PRINT "{CLS}" INPUT "ENTER WIDTH". Clear the computer's memory by typing NEW (RETURN). . and when you type in the information you must use a comma to separate the items. It is possible to use one INPUT command to input two or more numbers or strings. If you press RETURN before entering all the items the 64 will print two question marks and wait for the remaining items. Let's use what we know about variables and INPUT to improve the area program. HEIGHT AREA = WIDTH * HEIGHT PRINT: PRINT "AREA = " AREA This program will read the two numbers you type in for width and height and print the area of the rectangle. AGE PRINT NAME$ PRINT AGE The variables must have commas separating them in the INPUT command. and then type in this program. WIDTH INPUT "ENTER HEIGHT". AGE".Programming 31 semicolon between the message and the variable which will store the number.NAME$.

NEW deletes a pro gram from the computer's memory. three months later you may have forgotten. SUMMARY PROGRAMS A program is a numbered sequence of computer instructions.· VARIABLES Variables represent numbers and words In programs. Remarks are identified by the word REM before the remark and have no effect when the program is RUN.32 The Commodore 64 Omnibus . There are three types ofvariable: . You should always put plenty of remarks in programs. RUN starts the execution of a program. If you need to modify a program at some time after wri ting i t. remarks will make it much easier to remember how the program works. LIST displays the lines of a pro gram. These are used to hold comments. notes and titles to make the purpose of a program and the way in which it works clear to someone reading the listing.Part 1 REMARKS Line 10 of the last program is aremark or comment statement. because although you may understand how a program works when you write it.

and distinguished by $ after the name. but with distinguishing reference numbers. wi th the same variable name. Integer representing whole numbers. INPUT is used to enter numbers or words into variables while a program is running. String representing words or numbers. Variables may be collected in arrays. .Programming 33 Real representing any numbers. and distinguished by % at the end of the variable name. REMARKS REM is used to put remarks into pro grams for the programmer's benefit.

NEXT instructions work like this: FOR . as instructions which must be repeated need to be written only once.• NEXT LOOPS The section of pro gram between the FO Rand the NEXT commands is repeated for each value of COUNT. which are obeyed in order from beginning to end. The FOR .. In this chapter we will find out how to write programs in which some instructions are executed more than once. We will also discover that the computer can make decisions.. . and COUNT is automatically increased by one every time the NEXT command is met. Try this example: 10 20 30 FOR COUNT = 1 TO 10 PRINT COUNT NEXT COUNT which prints the numbers from 1 to 10 on the screen..CHAPTER 5 PROGRAM CONTROL In the last chapter we defined a program as a numbered list of instructions to the computer. REPETITION A section of program can be repeated many times using the instructions FOR and NEXT. This makes programs more efficient.

NEXT loop need not be increased by one. The STEP can also be negative. but you will be as you write the program! To recap. 30 NEXT would work just as well. . Y and Z may be variables or numbers). and not elements of arrays. COUNT is now increased by 3 each time the loop is repeated. any increase or decrease can be specified using the command STEP. Try changing line 10 to: 10 FOR COUNT = 0 TO 30 STEP 3 Then RUN the program again. The variables used in FOR . NEXT loops may be real or integer variables. the instructions are used like this: FOR V = X TO Y STEP Z is used to begin a loop (V is a variable and X.Program Control 35 The variable in a FOR . so that the numbers get smaller: 10 FOR COUNT = 50 TO 0 STEP -2. and NEXT V marks the end ofthe loop..5 It is not necessary to specify the variable after NEXT. However when you write longer programs you will find that they are clearer if the variables are always specified. but not string variables.... The 64 will not be confused.

The Commodore 64 Omnibus . B 40 NEXT B 50 NEXT A END The two loops are arranged so that one is completely within the other.. NEXT loops can be nested .Part 1 36 NESTED LOOPS FOR . L START 10 FOR A = 1 TO 5 20 FOR B = 1 TO 5 30 PRINT A. one loop can be contain one or more other loops. B NEXT B NEXT A For any nested loops. To clarify this.. otherwise the program will not work.. This rule always applies to FOR . Here is anexample: 10 20 30 40 50 FOR A = 1 TO 3 FOR B = 1 TO 4 PRINT A.. NEXT loops the loops must always be one within the next. If lines 40 and 50 were swapped over. You can see that the two loops overlap and the order in which the instructions should be obeyed is not clear. r+ [1.that is. . let's examine the order in which instructions are obeyed in the program. the result would be as shown opposite. it is very important that the enclosed loop is completely within the outer loop.

The previo us progr am would theref ore end: 40 NEXT B. B 40 NEXT A 50 NEXT B END Nine is the maxim um possible numb er of FOR •. Enter this progr am 10 20 GOTO 30 PRINT "LINE 20" . If you write a pro gram with too many loops neste d withi n each other . when it is RUN the 64 will print the messa ge 'OUT OF MEM ORY ERROR'.Progra m Contra ' ~ 37 START 10 FOR A = 1 TO 5 20 FOR B = 1 TO 5 30 PRINT A.. JUMPS The comp uter can be instru cted to jump from one progr am line to anoth er using the comm and GOTO .. NOTE Wher e two or more neste d FO R .• NEX T loops which can be neste d one withi n anoth er. A Again the order of the varia bles in line 40 is the rever se of the order in which the corre spon ding FOR comm ands occur. NEX T loops have their NEX T comm ands one after the other they may be combined by specif ying both or all the varia bles after one NEXT .

(Note that GOTO can be typed with or without aspace .) The jump can be to a lower numbered line. but for accurate timing. unless you stop it by pressing the RUN/STOP key: 10 20 PRINT "ON AND ".GO TO works equally well. The following pro gram is an example : 10 20 30 FOR 1= 0 TO 5000 NEXT I PRINT "ABOUT 5 SECONDS" This technique is fine for crude pauses..38 The Commodore 64 Omnibus . the duration ofwhich is not critical. TH E SYSTEM CLOCK Whenever you switch on your 64. NEXT loop which does nothing at all except count its way through the steps.Part 1 30 PRINT "LINE 30" When i t is RUN the message 'LINE 20' is not seen because the GOTO instruction in line 10 sends the 64 straight to line 30.. For pauses. we can use a FOR . and will continue to run until you switch off the machine. it is better to employ a second technique. GOTO 10 This is called an endless loop. The following pro gram will go on for ever. and is to be avoided! PAUSES There are two ways to instruct the computer to pause during the RUNning of a program. a built in clock starts running. The clock continually .

as the following program demonstrates. min u tes and seconds. The first two digits are hours. We can use this as a timer for precise pauses within a program. for example: 10 20 30 40 50 INPUT "DELAY IN SECONDS". the middle two minutes.0 . and the right hand pair seconds. TI$ is a six character string which indicates time since the computer was swi tched on in hours. one minute has elapsed when the value of TI has increased by 3600. TI$ can also be used to reset the system dock. with a statement like : TI$ = "000000" We can see TI$ in operation in this short program: 10 20 30 40 PRINT "{CLS}" TI$ = "000000" PRINT" {HOM}" TI$ GOTO 30 Here is a longer pro gram which makes use of the system dock to simulate a digital alarm dock: 10 PRINT "{RED}":POKE 53281.Program Control 39 updates the variable TI every 60th of a second. 10 20 30 PRINT "{CLS}" PRINT "{HOM}" TI GOTO 20 Since TI is updated every 60th of a second.D T = TI IF TI>= T+(D*60) THEN GOTO 50 GOTO 30 PRINT D " SEC DELAY!!!" An easier way of using the system dock is to use another system variable TI$.

15 GET K$:IF K$="" THEN 30 IF K$="{Fl}" THEN 200 IF K$="{F3}" THEN 300 IF K$="{F5}" THEN 400 IF K$="{F7}" THEN 500 GOTO 30 REM REM ************ REM * * REM * SET TIME * REM * * REM ************ REM INPUT "{CLS}{CO}{CO}{CO}{CO} {CO} CURRENT TIME"."RIGHT$(TI$.2) IF AS=O THEN 100 IF TI$=AT$ THEN POKE 53280.3.2)".2: POKE 54296.2)".40 The Commodore 64 Omnibus ." MIO$(TI$.AT$ IF AT$="" THEN 20 A$=AT$:GOSUB 1000 IF OK=l THEN AS=l:GOTO 20 GOTO 300 REM .CT$ IF CT$="" THEN 20 A$=CT$:GOSUB 1000 IF OK=l THEN TI$=CT$:GOTO 20 GOTO 200 REM REM ************* REM * * REM * SET ALARM * REM * * REM ************* REM INPUT "{CLS}{CO}{CO}{CO}{CO} {CO} ALARM TIME".Part 1 15 20 30 40 50 60 100 110 120 130 140 150 193 194 195 196 197 198 199 200 210 220 230 240 293 294 295 296 297 298 299 300 310 320 330 340 393 GOSUB 700 PRINT"{CLS}" PRINT"{HOM}" PRINT TAB(16)LEFT$(TI$.

0 AS=O GOTO 430 REM REM *************** REM * * REM * ALARM NOISE * REM * * REM *************** REM POKE 54278.245 POKE 54276.83 POKE 54277.Program Control 394 395 396 397 398 399 400 410 420 430 440 450 493 494 495 496 497 498 499 500 510 520 693 694 695 696 697 698 699 700 710 720 730 740 750 993 994 995 REM ************** REM * * REM * ALARM TIME * REM * * REM ************** REM IF AS=O THEN 30 IF AF=1 THEN 430 PRINT"{HOM}{CD}{CD}"TAB(28) LEFT$(AT$."RIGHT$(AT$.33 POKE 54273.18 POKE 54272.3.209 RETURN REM REM *************** REM * * 41 ."MID$(AT$.14:POKE 54296.2}:GOTO 440 PRINT "{HOM}{CD){CD}"TAB(28) 11 ":REM 10 SPACES AF=I-AF GOTO 30 REM REM ************* REM * * REM * ALARM OFF * REM * * REM ************* REM POKE 53280.2)".2) ".

If the alarm is set and the current time . F5 displays the alarm time if i t is set.2))<24 THEN 1030 GOTO 1060 IF VAL(MID$(A$. F7 turns the alarm offin lines 500 to 530. minutes and seconds. F3 allows you to set the alarm time using lines 300 to 340.Part 1 996 997 998 999 1000 1010 1020 1030 1040 1050 1060 REM * CHECK ENTRY * REM * * REM *************** REM OK=O IF VAL(LEFT$(A$. Line 40 prints the current value of TI$ as hours. Lines 100 to 150 control the mode ofthe dock: F1 allows you to set the current time using lines 200 to 240.3. if i t is already displayed.2))<60 THEN OK=l RETURN Program Description Line 10 sets the foreground colour to red and the screen colour to black.42 The Commodore 64 Omnibus . the pro gram jumps to the appropriate section. or. cancels the display. If a key is pressed. The program loops continuosly through the first section checking for key presses and comparing the current time with the set alarm time. separated by a full stop.2))<60 THEN 1050 GOTO 1060 IF VAL(RIGHT$(A$.

• THEN is: IF (condition) THEN (instructions) The condition after IF may be one ofmany possible alternatives.. in thiscase 10. it is checked for validity by the subroutine at line 1000. the screen border turns red and a noise (set up in lines 700 to 750) is switched on. by setting the variable OK to 1. and one of two alternative actions is taken. IF COUNT < 100 Continue when variable less than a number. 10 20 30 40 50 FOR X = 1 TO 10 PRINT X IF X = 5 THEN PRINT "X = 5" FOR P = 0 TO 2000 NEXT P NEXT X The format of IF .Program Control 43 matches the alarm time. depending on the result ofthe test. When an entry is made to set the time. A variable is tested. IF COUNT > NUMBER . Example are: IF COUNT = 10 Continue when variable (COUNT) equals a number. DECISIONS The commands IF and THEN are used in programs to make decisions. which indicates to the calling pro gram that the entered time conforms to the 24 hour dock format.

The instructions after THEN are carried out if the condition is met. IF X <= Y Less than or equal to. THEN can also be used to controljumps: 10 20 30 INPUT "WHAT NUMBER AM I THINKING OF". otherwise the pro gram continues at the next line. Two condi tions may be combined.. IF NUMBER < > VALUE One variable not equal to another (greater than or less than). IF . A$ . IF X >= Y Greater than or equal to. Logical Thinking. as in: IF X = 1 OR X = IF A = 3 AND NAME$ 2 = "CBM 64" In all of these.The Commodore 64 Omnibus . or one may be a variable and the other a number.Part 1 44 Continue when variable greater than a number. the items being compared may both be variables. N IF N < > 3 THEN PRINT "WRONG" : GOTO 10 PRINT "CORRECTt" Ifthejump is the only instruction after THEN. the word GOTO can be omitted: 10 INPUT "WHAT AM I". (There's not much point in comparing two numbers!) For further details see Chapter 9..

TRY AGAIN" PRINT GOTO 10 PRINT: PRINT"GOOD GUESS!" EXAMPLE PROGRAM .S(10) REM INPUT 10 NUMBERS PRINT "{CLS}" FOR N=l TO 10 INPUT"ENTER A NUMBER".Program Control 20 30 40 50 60 45 IF A$ = "CBM 64" THEN 60 PRINT: PRINT A$"? NO.NUM(N) NEXT N REM COPY NUMBERS TO ARRAY S FOR C=l TO 10 S(C) = NUM(C) NEXT C REM SORT NUMBERS COUNT = 0 FOR N=l TO 9 IF S(N+1) >= S(N) THEN 280 TEMP = S(N+1) S(N+1) = S(N) S(N) = TEMP COUNT = COUNT + 1 NEXT N IF COUNT <> 0 THEN 210 FOR Z=l TO 10 PRINT NUM(Z).SORTING NUMBERS As an example of what can be done using loops and decisions.S(Z) NEXT . here is a program which sorts ten numbers into ascending order. 10 20 30 40 50 60 70 100 110 120 130 200 210 220 230 240 250 260 270 280 300 310 320 330 REM SORTING PROGRAM DIM NUM(10).

COUNT... Lines 110 to 130 copy the numbers from NUM( ) to a second array 8( ) which will be sorted. the loop is repeated. The lines from 210 to 280 sort the numbers in the array 8(10) into ascending order. keeps track of the number oftheseswaps and. (This is not strictly necessary for ten numbers... The computer is diverted from the main pro gram to the subroutine.Part 1 The REMarks are used to indicate the functions of the different sections of the program. using a FO R . but it would be if any more were to be sorted. The command GOSUB followed by a line number or a variable diverts the computer to the .46 The Commodore 64 Omnibus .. NEXT loop is used. but is written only once. SUBRQUTINES A subroutine is a section of program which is executed at a number of different times in the course of a program. Lines 310 to 330 complete the program by PRINTing the two sets ofnumbers. while NUM retains the numbers in the order in which they were typed in. which works like this: Line 20 dimensions the two arrays used in the program. NEXT loop. and returns to the main program at the point from which it left. ifat the end ofthe loop this isn't zero. A FOR . and swaps them over if they are in the wrong order. Again.) Lines 40 to 70 input ten numbers from the keyboard and store them in the array NUM( ). A variable. NEXT loop compares each element ofthe array 8 with the next. a FOR ..

B RETURN REM SUBROUTINE TO DISPLAY RESULT PRINT "{CLS}" PRINT PRINT A "+" B " = " C RETURN Lines 10 to 40 are the main program. Line 10 calls the subroutine at line 110. and the T . at the lowest numbered line. line 10. B". hIS li ne calls the first subroutine. line 20 adds A and B and stores the result as C.Program Control 47 subroutine in much the same way as the GOTO command. The difference is that the end of a subroutine is marked by aRETURN command which sends the computer back to the instruction after the GOSUB command. S ~lways. and line 30 calls the subroutine at line 210. The subroutine at li ne 210 clears the screen and prints the two numbers and their sumo When the program is RUN. Line 40 marks the end of the program . As an example of two very simple subroutines. the computer begins. The subroutine at line 110 inputs two numbers and stores them as A and B. A. which contain the su brou the last line to be executed is not the last line of the pro gram we have to tell the 64 not to go on to the next lines. type in the following program: 10 20 30 40 100 110 120 200 210 220 230 240 GOSUB 110 C = A+B GOSUB 210 END REM SUBROUTINE TO INPUT A & B INPUT "A.

the programmer . to follow. the subroutines may call other subroutines. The use of subroutines saves a lot of effort in wri ting programs. The command tells the computer to stop running the program.that is. Line 240 returns the computer to line 40. which may in turn call others. However a subroutine may not be called by another subroutine which has been called by the first one. There is a . like loops. as the program lines in the subroutine need to be written only once. The pro gram proceeds as normal to line 30. Line 120 returns the computer to the instruction after the GOSUB.Part 1 computer is diverted to line 110. So. STOPPING AND STARTING In the last example pro gram the new command END was used to indicate the last line of the program to be executed. There is no limit to the number of times a subroutine may be called. A maximum of twenty-four subroutines may be nested like this. which is in li ne 20. instead of being retyped at every point in the program where they are needed.48 The Commodore 64 Omnibus . Subroutines. Another advantage of subroutines is that they can make the design of a program simpler. may be nested . If you use subroutines for the repetitive and less important parts of a pro gram the main program becomes much easier for you. and is therefore much easier to write. and the RETURN command ends the diversion. or an endless loop occurs. which causes another diversion to line 210. and the program ends. and the pro gram will crash when the 64 runs out of the memory it uses to store all the line numbers for the RETURNs. a GOSUB command causes a diversion from the sequence of a pro gram to a subroutine.

STO P. 200. The program will continue from the instruction after the last one to have been executed. CONT may only be used immediately after the program has been stopped: if you have altered the program the message '?CAN'T CONTINUE ERROR' will be displayed. or by holding down CTRL and pressing C.. but when STOP is used the program halts and the message 'BREAK IN LINE xxx' is printed (xxx is the line number of the STOP instruction). but the two have slightly different effects. and the 'Ready' message is displayed. END stops the program running.. ON . You may not use CONT within programs.Program Control 49 second command. If a pro gram has been stopped by one of these instructions. as this will give a '?SYNTAX ERROR'. ON N GOTO 100. GOSUB (GOTO) Both GOSUB and GOTO may be used in a second type of decision command which selects one of a number of destinations depending on the value of a chosen variable. which also halts programs. it may be restarted with the instruction CONT. Unless you need to know where the program halted. 300 results in GOTO 100 if N GOTO 200 if N GOTO 300 if N Similarly: = = = 1 2 3 . END is the one to use.

Loops may be nested one within another.. SUMMARY -LOOPS The loop structure has the form: FOR V = A TO B STEP C . The condi tion after IF is usually a test of a variable. NEXT in which the instructions between the FO Rand NEXT commands are repeated once for each value ofV indicated by the FOR .500. V must be a variable. no destination is selected and the program continues at the next instruction. The complete IF . STEP command. GOTO need not be included if it would be the only command after THEN. A... DECISIONS IF (condition) THEN (instruction) decides between two actions.100 selects the P'th destination in the list and calls it as a subroutine. There may be more than one instruction after THEN.400.. THEN command must be in one line.200. Ifthe value ofthe variable is greater than the number of destinations in the list..50 The Commodore 64 Omnibus . in which ca se colons (:) must be used to separate them.Part 1 ON P GOSUB 500. B and C may be variables or numbers. or if it is zero or less.. but it must be if there is another command before i t: 100 IF ACE hut = 1 THEN 20 100 IF ACE = 2 THEN KING 7:GOT020 = .

.if there is an N'th i tem in the list... RETURN at the end of the subroutine returns the computer to the instruction after the GOSUB. GOSUB ON . Y. Z causes a GOSUB to the P'th item in the list. END halts the running of a program. B. ON . ON P GOSUB X.. C This causes a jump to the N'th destination . . using GOSUB and RETURN. GOTO Selects adestination from a list: ON N GOTO A. GOSUB calls the subroutine.Program Control 51 SUBROUTINES Diversions from a program. STOP halts a program and prints 'BREAK IN LINE xxx': CONT will restart a pro gram if the pro gram has not been altered.

and we will also examine in more detail the use of PRINT and other commands to display data. The program will continue to loop in this way until a key is being pressed at the same time as line 10 is being executed. if any. for a key press. GET The G ET command can be used in two ways: Firstly. is being pressed as the program runs through. a blank li ne is printed and the program loops round to check again . There are several ways of getting information into pro grams which we will examine in this chapter. nor by which pro grams can print out information on to the screen. GET which reads a single character from the keyboard.CHAPTER 6 DATA AND PROGRAMS So far we have not examined all of the ways in which information can be given to programs. it can be used to check which key. as in this example: 10 20 30 GET A$ PRINT A$ GOTO 10 Note that if no key is pressed. . There is a BASIC command.

then only the number keys. READ. Pressing any other key will cause the computer to halt the program and print a 'SYNTAX ERROR' message. + and . and the keys used in relation to numbers (. The G ET command is useful in pro grams which ask the operator to select an option.) may be pressed. We can demonstrate this with a modified version ofthe last program: 10 15 20 30 GET A$ IF A$ = "" THEN 10 PRINT A$ GOTO 10 The extra instruction in li ne 15 causes the program to loop between lines 10 and 15 until a key is pressed. When a key is pressed the character of that key is assigned to the variable A$. or answer Yes orNo: 10 20 30 40 PRINT"PRESS C TO CLEAR SCREEN" GET YN$ : IF YN$ = "" THEN 20 IF YN$ = "C" THEN PRINT "{CLS}":END GOTO 10 READ AND DATA To enter large amounts of data which will be the same each time the program is RUN we use the final type ofdata entry command.Data and Programs 53 The GET command can also be used to halt a pro gram in order to wai t for a key to be pressed. The character of the key which is then pressed is stored as a specified variable. Look at this program: . If you change the variable in line 10 from astring variable to a numeric variable.

This means you . Imagine the typing involved in entering lots oflines like MTH$(2)="FEBRUARY" With DATA lines you can layout the information in a clear tabular form and check it much more easily. You can also alter i t if you need to wi thou t touching the main pro gram.31. and the pointer moves on to the next item.54 The Commodore 64 Omnibus .30 DATA JULY.OCTOBER.31.30 DATA MAY. APRlL.31 The information for this program is written into the program in lines 1000 to 1050. The information is copied into the arrays MTH$ and DA YS by the READ commands in line 30 and 40. the DATA item indicated by the pointer is copied into the variable. DECEMBER.Part 1 10 20 30 40 50 60 1000 1010 1020 1030 1040 1050 DlM MTH$(12): DlM DAYS(12) FOR M = 1 TO 12 READ MTH$(M) READ DAYS(M) PRlNT MTH$(M)" HAS "DAYS(M)" DAYS" NEXT M DATA JANUARY.30 . JUNE. the computer uses a tpointer' stored in its memory to keep track of how many DATA items it has read. FEBRUARY.30.28 DATA MARCH. AUGUST. Every time a READ command is met. 31. Each item of DATA is separated from the next by a comma (or the end of a line).31.31 DATA NOVEMBER. When a program is running.31 DATA SEPTEMBER. This method of entering information is much easier to use than simply writing it into the program by setting variables.

Integer variables must find integral numbers. but READ with a number variable must find a number in the DATA entry or a 'SYNTAX ERROR' will result. Output on the screen is formatted at every tenth column. "D" will give a display: A B e D . "e". PRINT "A". The 64 has a number of extra facilities which allow you to control the screen layout and produce clear and orderly output from programs. A READ with astring variable will read anything as astring. real variables may read decimal fractions as weIl. MORE ABOUT PRINTING So far. and the 64 will print 'OUT OF DATA ERROR'. in a PRINT statement. The variables used in the READ command must match the type of data in the corresponding DAT A entry. You can use commas to separate the items. For example. we have described the use of PRINT (or ?) simply to display single items of data on the screen. PUNCTUATING PRINT STATEMENTS You can PRINT more than one item on a single line by including 'punctuation' in the PRINT command. The command RESTORE can be used to reset the data pointer to the first DA T A i tem in the program. "B". and the effect is rather like the 'tab' function of a typewri ter.55 Data and Programs must have a DATA entry corresponding to each occurrence of READ: the program will stop if there are too many READ commands.

The Commodore 64 Omnibus . This leaves no space between successive items in the PRINT statement. and real and integer variables.the first after a commaappears in column 10. PRINT "{CLS}I AM" SPC(lO) "CBM 64" will print 10 spaces between ~I AM' and ~CBM 64'. SPC(N) SPC(N) teIls the 64 to PRINT N spaces.Part 1 56 The first item in the PRINT statement appears in column O.) can be used in a similar fashion. except that aspace is printed on either side of each number. "0". The leading space takes the minus sign when negative numbers are displayed. PRINT "A". The next item . The other items appear in columns 20 and 30. "E". "C". "F" will display: ABCOEF The same rules apply when printing numbers. with spaces as appropriate. The effect of commas and semicolons is not confined to the PRINT statement in which they appear. "B". . The semicolon (. If you end one PRINT statement with a comma or semicolon then the data printed by the next PRINT command will appear on the same line.SPC and TAB. You can exercise further con trol over the formatting of screen displays using two more BASIC commands .

Data and Programs 57 TAB(N) The TAB command instructs the 64 to move the cursor N spaces from the left side of the screen before printing. For example.any number or letter can be used. PRINT TAB(17) "CBM 64" displays fCBM 64' in the middle of a screen line. . SPC. The 64 interprets four characters as control codes governing the cursor movement. PRINT SPC(IO). its current li ne . TAB moves the cursor to a column position on what is. The difference between SPC and TAB is straightforward. moves the cursor onwards by up to 255 spaces. in effect.: PRINT POS (0) gives the value 10. on the other that they will not delete data which is left on the screen when new data is PRINTed. so can embrace several lines if necessary.) CURSOR CONTROL J ust as we can use the cursor keys to move the cursor round the screen. There is a function POS corresponding to the TAB command wh ich returns the number of the column in which the cursor is placed. since the cursor was in column 10 after the first PRINT command. Wh at neither do is to overprint blank spaces . For has a maximum value of 39. (The number in brackets has no significance . so can we use a pro gram to move it.

G ET does not normally wait for a key to be pressed be fore continuing. The way in which data is presented on the screen is an important part of the program and can make the difference between a program being easy to use. SUMMARY GET is used to assign a keystroke value from the keyboard to a variable. or frustrating and confusing. READ and DAT Aare used to copy large amounts of information into variables without writing lots of program lines. . for example: 10 20 30 40 50 60 70 80 PRINT "{CLS}" PRINT "TOP LINE" CD$ = "{10 * CD}" CU$ = "{12 * CU}" FOR DELAY = 0 TO 3000:NEXT PRINT CD$"MIDDLE LINE" FOR DELAY = 0 TO 3000:NEXT PRINT CU$ "BACK TO THE TOP!" prints the three messages in various parts of the screen using the strings CD$ and CU$ to move the cursor. and it is usual to include programming to ensure that it does.The Commodore 64 Omnibus .Part 1 58 The characters can be used wi thin strings. PRINTING There are a number of special commands which allow control of the format of data displayed on the screen.

of characters. figures. These may be letters. There are a number of BASIC commands which are used to manipulate strings. punctuation marks. TYING STRINGS TOGETHER Strings can be added together. We saw in Chapter 4 that astring variable can store a sequence of characters. and these are described in this chapter. 10 20 30 A$ = "FLORENCE" B$ = "NIGHTINGALE" SPACE$ = " " . For example: NAME $ = "WILLIAM SHAKESPEARE" GAME $ =" SPACE INVADERS" = "ABC123D" REFERENCE$ Astring can hold up to 255 characters. in fact any of the eharacters the 64 can print. Try this: 10 20 NAME$ = "JOHN SMITH" PRINT LEN(NAME$) This program prints the number 10. which is the number of characters in NAME$ (including the space). The number of characters in astring can be counted using the function LE N.CHAPTER 7 PIECES OF STRINGS String variables are used to store sequences 'strings' . spaces.

RIGHT$ reads from the end of the string. and 10 20 S$ = "UVWXYZ" N=3 . CUnlNG STRINGS There are three BASIC functions which are used to extract information from strings. If a pro gram tries to add too many characters together. For example: PRINT LEFT$ ("ABCDEFG".The Commodore 64 Omnibus .but don't forget that you can't have astring longer than 255 characters.Part 1 60 40 50 NAME$ = A$ + SPACE$ + B$ PRINT NAME$ Notice that strings don't add like numbers. Adding strings is called concatenation and this is how really long strings are constructed .4) displays tABCD' . number) The string in the brackets may be a variable or an actual sequence of characters between quotation marks ("). B$ + A$ does not give the same result as A$ + B$. and the number may be a number or a variable. LEFT$ is used to read characters from the beginning of astring. The functions are: LEFT$ RIGHT$ and MID$ LEFT$ and RIGHT$ are both very similar in operation. the 64 will print a tSTRING TOO LONG ERROR' message on the screen and stop the pro gram. The functions are used like this: LEFT$ (string.

The third function. beginning at the third.Pieces of Strings 30 40 61 R$ = RIGHT$ (S$. . but also where in the string the characters are to be found. Each letter. MID$.3.the American Standard Code for Information Interchange . all characters to the right of and including the specified character are included. and each of the other characters the 64 can print. The 64 uses a system called ASCII .4) prints four characters. PRINT MID$ ("12345678".which is the most common system for micros. is represented by a different code number.N) PRINT R$ displays 'XYZ'. There are several systems used in different computers for deciding which code number represents which letter. is a li ttle more" complex. of '12345678': so it prints '3456'. Ifyou do not specify the number of characters to be read. The table in Appendix 16 shows how the ASen code relates to letters and numbers. In fact the 64 also uses a variant of ASen in certain circumstances. Therefore: PRINT MID$ ("ABCDEFGHIJK". as we have to specify not only the string and the number of characters to be read. signs and letters) directly . 4) displays 'DEFGHIJK'.they use numbers to symbolise the characters. but more ofthat later. NUMBERS AND LEITERS Computers cannot handle characters (numbers.

what use is this knowledge? There are two functions in BASIC which allow us to convert characters to numbers and numbers to characters. or the computer will complain of an 'ILLEGAL QUANTITY ERROR'. The function CHR$ converts a number to astring containing the corresponding character: 10 20 30 C = 65 A$ = CHR$(C) PRINT A$ This displays the letter 'A'. code number 66 for Band so on. You can use a variable with CHR$.The Commodore 64 Omnibus . For example the character '9' has the code number 57. Even numerals have codes.Part 1 62 From this table we see that the 64 uses a code number 65 to represent the letter A. You can also use string variables with ASC: 10 20 B$ = "B" PRINT ASC(B$) . CHR$ can only give one character at a time. which is the ASCn code for the letter B. The function ASC complements CHR$. ASC finds the ASCn codes of characters. 10 20 B = ASC("B") PRINT B displays '66'. and the number or the variable inside the brackets must be less than 255. WeIl. or a number: PRINT CHR$(42) This displays an asterisk (*). as in the example.

This means that: . The function STR$ creates from a number astring containing the characters ofthat number: 10 20 A$ = STR$(12345) PRINT A$ This converts the single number 12345 into a string by assigning the characters 12345 to A$ and displays the string. V AL evaluates the numerical characters in a string: 10 20 30 A$ = "123456" A = VAL(A$) PRINT A This displays the number '123456'. . There are two functions which can be used to make strings of number characters from actual numerals and to find the numeric value of the number characters in astring. The complementary function to STR$ is V AL. ASe gives the code for the first character only: PRINT ASC( "ABCOE" ) displays '65'.including numerals. FIGURES IN STRINGS Astring can contain any characters . If the variable contains more than one character. If the string evaluated contains letters as weH as numbers then only the numbers which appear to the left of all the letters are converted by V AL.Pie ces of Strings 63 also displays '66'.

Memory location 650 controls the repeat key function on the 64.Part 7 PRINT VAL("123ABC45") displays '123'.. THEN. (In computing.may appear before the number characters. space and INSTIDEL keys to repeat. allowing only the the same way as numbers. G ETs the selection from the keyboard and then calls the selected routine. P$ IF P$ <> "BEANS" THEN PRINT "WRONG !!!": GOTO 10 PRINT "{CLS}O. Placing (POKEing) a value of 128 in this location causes all keys to repeat. TESTING STRINGS Strings can be compared with each other. They will be treated by V AL as the sign ofthe number. 10 20 30 40 50 60 PRINT"{CLS}" PRINT:PRINT"SELECT OPTION" PRINT:PRINT"S •• SCREEN COLOUR" PRINT:PRINT"B •• BORDER COLOUR" PRINT:PRINT"K •• KEY REPEAT" GET K$:IF K$="" THEN 60 . using IF .64 The Commodore 64 Omnibus . a menu is a list of options displayed on the screen to the program operator.." Another use for comparing strings is when the GET command is used in conjunction with a 'menu'.) The next program displays a simple menu of display options. A routine like this one can be used to check that an entry is suitable for the program: 10 20 30 INPUT "WHAT'S THE PASSWORD".K. The signs + and . and normally contains a 0.

This is because any number which is shown as a result of using STR$ is preceded by aspace (or a minus sign if negative).0:GOTO 60 Warning Be careful when using STR$ and making comparisons.Pieces of Strings 70 80 90 100 1000 1010 1020 1030 2000 2010 65 IF K$="S" THEN REG=53281:GOTO 1000 IF K$="B" THEN REG=53280:GOTO 1000 IF K$="K" THEN 2000 GOTO 60 O=PEEK(REG) IF 0=255 THEN 0=239 POKE REG.2) As weIl as testing to see if two strings are the same.0+1 GOTO 60 IF PEEK(650)=0 THEN POKE 650. you can use the 'greater than' and 'less than' ( > and <) tests to compare strings. The 64 is in fact comparing the ASCII codes of the letters in the strings. If you compare "123" with STR$ (123) you will find that the 64 thinks they are not the same.128:GOTO 60 POKE 650. you can get round the problem by using MID$ to remove the first character of the string: A$ = MIO$(STR$(123). However. This seems to be a feature shared by all Commodore machines. 10 IF "B" > "A" THEN PRINT "OK" This works because the letters are stored as numbers. This is very .

If you wish to sort fewer than 20 strings. which may contain more than one word. Notice that any characters will be sorted into ASCII order.Part 1 66 useful because it allows strings to be sorted into alphabeticalorder: 10 20 30 40 50 60 99 100 110 120 130 140 150 160 170 180 190 200 999 1000 1010 1020 1030 1040 PRINT "{CLS}" DIM W$(20) C = O:L = 0 INPUT "ENTER A WORD". this will tell the program tha t there are no more strings to come.W$(C) IF W$(C) = "ZZZ" OR C = 20 THEN C = C-l:PRINT"{CLS}": GOSUB 1000:GOTO 100 C = C+l:GOTO 40 REM SORT STRINGS S = O:L = 20 FOR Z=O TO C IF W$(Z+l»W$(Z) THEN 170 TEMP$ = W$(Z+l) W$(Z+l) = W$(Z) W$(Z) = TEMP$ S = S+l NEXT Z IF S <> 0 THEN 100 PRINT "{CLS}" GOSUB 1000:END REM DISPLAY NUMBERS PRINT"{CLS}" FÜR P = 0 TO C PRINT TAB(L)W$(P) NEXT P RETURN This program works in the same way as the sorting program at the end of Chapter 5. Y ou can input up to twenty strings. so strings like *I@f-?% and I@$&)# will be sorted.The Commodore 64 Omnibus . . If you run this program a few times you will discover how effective string sorting can be. then enter ZZZ as the last string.

because of course they are represented by different codes. Finally. combining most of the ideas in this chapter to give you agame of Hangman. and the 64 is interested only in the codes. here is a more light hearted demonstration of string handling. so they appear at the end ofthe sorted list. You can of course change the tdictionary' to suit yourself. 5 6 7 8 9 10 20 30 40 50 60 70 80 90 93 94 95 96 97 98 99 100 110 REM *********** REM * * REM * HANGMAN * REM * * REM *********** REM POKE 53280.13: PRlNT"{GR1}" PRINT"{CLS}{CO}" TAB(15)"{RVS} HANGMAN {ROF}" OlM 0$(30) G=l:W=O:CF=O:W$="" FOR Z=OT030 REAO O$(Z):NEXT Z FOR z=o TO 9 REAO D(Z). The lower case letters have higher codes than the capitals. (You can switch in and out oflower case by pressing the CBM key and the SHIFT key simultaneously).A(Z):NEXTZ REM REM **************** REM * * REM * DRAW GALLOWS * REM * * REM **************** REM Gl$=CHR$(176)+CHR$(195)+CHR$ (195)+CHR$(174) G2$=CHR$(221) .Pieces of Strings 67 You will find that lower case letters are treated as completely different.5:POKE53281.

Z."i:NEXT PRINT"{HOM}{CD}"TAB(30) "GUESS 243 244 245 246 247 248 249 250 255 260 265 270 275 280 REM REM ******************** REM * * REM * INPUT YOUR GUESS * REM * * REM ******************** REM GET G$:IF G$=""THEN 250 IF G$<"A" OR G$>"Z" THEN 250 FOR Z=l TO LEN(U$) IF G$=MID$(U$.Part 1 120 G3$=CHR$(183)+CHR$(183)+CHR$ (183)+CHR$(183)+CHR$(183)+"{CU) 130 140 150 160 183 184 185 186 187 188 189 190 200 210 220 230 240 PRINT"{CD}{CD}{CD}{CD}" PRINT TAB(6)Gl$ FOR z=o T05:PRINTTAB(6)G2$:NEXT PRINT TAB(4)G3$ REM REM ******************** REM * * REM * RANDOM SELECTION * REM * * REM ******************** REM N = INT(RND(1)*31) C$ = D$(N) L = LEN(C$) FOR Z=l TO L PRINT TAB(14)".68 The Commodore 64 Omnibus .l) THEN 250 NEXT Z G=G+l:U$=U$+G$:GOSUB 400 IF W=10 THEN M$="{RED} YOU LOSE!!":GOSUB 360:GOTO 310 IF C=L THEN M$="{RED} YOU WIN!!" : GOTO 310 GOTO 240 PRINT" {HOM} {CD}"M$ 290 300 310 " " iG .

l)" "j:NEXT: RETURN 393 REM 394 REM *************** * 395 REM * 396 REM * CHECK GUESS * * 397 REM * 398 REM *************** 399 REM 400 FOR J=l TO L 410 IF MID$(C$. "MEMORY"." PRINT"."LIST" 1010 DATA "BUFFER"."DATA".J."CURSOR". 370 FOR Z=l TO L 380 PRINT MID$(C$."BINARY". "REGISTER"."BASIC".l)=G~THEN CF=l: C=C+1:PRINT"{HOM}{14 * CD}" TAB(12+2*J)G$ 420 NEXT J 430 IF CF=l THEN 480 440 W$=W$+G$ 450 PRINT"{HOM}{22 * CD}"TAB(5)W$ 460 POKE A(W).6 470 W = W+1 480 CF = O:RETURN 993 REM 994 REM *********************** 995 REM * * 996 REM * DATA FOR DICTIONARY * * 997 REM * 998 REM *********************** 999 REM 1000 DATA "BYTE"."SERIAL"."PEEK".Pieces of Strings 320 69 PRINT"{HOM}{18 * CD}"TAB(ll)" ANOTHER GO (Y/N)?" 330 GET A$: IF A$='"'THEN 330 340 IF A$="Y" THEN RUN 350 PRINT "{CLS}":END 360 PRINT" {HOM} {14 * CD} "TAB (14 )."SEQUENTIAL"."POKE"."P ARALLEL" .Z.D(W):POKEA(W)+54272.

91.1474.1514 Program Description 20 . read the data for the dictionary into array D$( Z). 1030 1993 1994 1995 1996 1997 1998 1999 2000 2010 2020 2030 "ASCII". one for each letter of the word. "RESTORE".1392 DATA 110.103. "GOSUB" . "GRAPHIC" . 100 .90 Set up display. "SYNTA X".1472.70 The Commodore 64 Omnibus . 250 . read the data for the characters comprising the tvictim' into array D(Z) and the corresponding screen memory locations into array A( Z).93. "ARRAY".1473 DATA 103. "LOOP".1353."VARIABLE".99.380 Input a guess and check it for validity.1394.112. 190 ."ROM".1512 DATA 101.1433.240 Select a word at random from the dictionary and display a series of hyphens . Each time a letter is used it is placed in string U$.1393. which is then used to prevent a letter being picked more than once (lines 260-270).Part 1 1020 DATA "RAM"."SPRITE".160 Draw the gallows using keyboard graphics characters (see Chapter 11). "VE RIFY". Also controls the game and finishes it after ."BEANS" REM REM ********************** REM * * REM * DATA FOR CHARACTER * REM * * REM ********************** REM DATA 81.101. "INTEGER" DATA"SCROLL". "STRING".

These can be stored in string variables. If you lose. the correct answer is displayed by lines 360 . There is a table of the ASCII codes for the characters in Appendix 16. the appropriate letters are revealed in the answer. 400 .480 Check your guess against the chosen word and if correct. If not.Q)reads Q characters. LEFT$ (string. RIGHT$ and MID$ are used to separate parts of strings.P.M) reads the characters last M MID$ (string. LEN(string) gives the number of characters in a string. SUMMARY Astring is a sequence of characters.71 Pie ces of Strings 10 attempts have been made.380. Strings can be added together: PRINT "ABC" + "DEF" + "GHI" displays (ABCDEFGHI'. . starting at character P ASCII code is used by the 64 to symbolise letters. LEFT$. which are distinguished by $ after the variable name.N) takes the first N characters of the string RIGHT$ (string. one section of the victim is drawn by line 460.

and >. . COMPARISONS. STR$ turns a number into astring of number characters: 10 20 A$ = STR$(123) PRINT A$ V AL evaluates the numerical characters In a string: PRINT VAL("123ABC789") displays t123'.. Strings can be compared using IF . ASC gives the ASCII code for a character: PRINT ASC ( 11 A") displays t65'. < .Part 1 CHR$ converts a number to the equivalent character: PRINT CHR$(65) displays tA'. This is useful for testing inputs and sorting strings.72 The Commodore 64 Omnibus .. THEN and the relational operators =.

in Chapter 7 several functions were described which operate on numbers to give strings. on strings to give other strings. . or on strings to give numbers. 10 FOR N = 1 TO 10 20 PRINT N. There are a number of functions available on the Commodore 64. because 2 squared (2*2) is 4.CHAPTER 8 FUNCTIONS A (function' in computing is an instruction which performs a calculation on a number.) Try: PRINT SQR(4) The 64 displays 2. gives N. or squared. SQR(N) 30 NEXT prints the numbers 1 to 10 and their square roots. In this chapter we will look at some more ofthe functions available on the Commodore 64. For example. SQUARE ROOTS The square root of a number is calculated by the function SQR(N). (The square root of a number or variable N is the number which when multiplied by itself.

PRINT ABS( displayed.Part 1 ABSOLUTE VALUES The function ABS finds the absolute value of a number: the value of the numerical part. ABS rounds up to six decimal places. Be careful with numbers less than zero.the minus sign has been removed. Therefore: PRINT INT(-2.4567) Only the whole number part .74 The Commodore 64 Omnibus .no change. But PRINT ABS( -543. This means that for negative numbers the answer is not the whole part of the initial number. The INT function finds the first whole number lower then the number you give it. The function changes negative numbers to positive numbers.345) displays t 543. Try: PRINT INT(123.123 . but has no effect on positive numbers.875) . but one less (or minus one more!).456' . disregarding the sign.456) displays t123. INTEGER CONVERSION The function INT removes the fractional part of a number and returns the next lower whole number.345 ' .

the result is 1. They are written: SIN(N) COS(N) TAN(N) ATN(N) where N is a number or a variable. if the number is zero. so it follows that 360 degrees is equivalent to 21T radians. SG N returns -1. and if the number is less than zero. The circumference of a circle is 21T times its radius (21TR). tangent and aretangent are available In Commodore BASIC. To eonvert from degrees to . eosine.3°). From this we can work out that 1 degree is 21T/360 radians (about 0. and 1 radi an is 360/21T degrees (about 57.Functions 75 displays (-3'. the result is zero.175). In the diagram overleaf. A radi an is the ratio of the length of an are of a circle to the radius. Note that the angles on whieh these functions operate must be given in radians. not in degrees. the angle A in radi ans is L/R. PRINT SGN (5) PRINT SGN (0) PRINT SGN (-7) displays (1' displays (0'. SIGNS SGN(N) returns a value whieh indieates the sign of a number or variable N. Ifthe number is positive. TRIGONOMETRY The trigonometrieal functions of sine. and displays (_1'.


The Commodore 64 Omnibus - Part 1

,'" '" '"


L II "




The angle A is UR radians

radians multiply by 21T/360. The value of 1T can be
obtained on the CBM 64 by using the 1T symbol
(press SHIFT and t). To convert from radians to
degrees multiply by 360/21T.
So, the sine of 45 degrees (0.7071) is given by:
10 RAD = 2*1T/360
The arctangent of1 (45 degrees) is given by:
10 RAD = 2*1T/360

Natural logarithms are provided by the function
LOG( ).

displays '2.30258509'


displays '8.5171932'



The antilogs of natural logarithms are calculated
by EXP(N). Try:

The answer is 100.
Logs can be used to calculate roots. This program
finds the cube root of8.
10 A = 8
20 R = LOG(A)j3

The answer is 2, because 2 cubed (2*2*2) is 8.
This program calculates fifth roots.
10 N = 243
20 R = LOG(N)j5

The program will display t3', because 3 to the power
5 (3 t 5 or 3*3*3*3*3) is 243.

The 64 has a function which provides random
numbers. The function is RND(X), which prints a
number between 0 and 1. The tseed' value - X can be any number or letter, but does directly
influence the value of the random number that
results. Try PRINTing RND(1) a few times. You
will get a different number each time.
The random numbers provided by RND are not
truly trandom' - it is very difficult and expensive to
make a machine which will give perfectly random
numbers. If you switch your 64 off and on, and
immediately type PRINT RND ( 1 ) , you will get the
same number every time (on our 64 it's


The Commodore 64 Omnibus - Part 1

0.185564016). The random numbers are calculated
from a starting number, or seed, and any seed will
always produce the same sequence of numbers.
The random number calculation can be controlled
by altering the number or letter in the brackets.
You can give the computer a new seed for its
random number generator by putting a negative
number in the function. Try PRINT RND ( - X). The
resulting number is not much use, but the effect of
the command is to give a new seed number to the
random number generator. Try PRINTing five
numbers with RND(l) and make a note ofthem. If
you then re-seed the random number generator
with 1 by PRINTing RND(-l) again, and
rePRINT five numbers with RND(l), you will get
the same sequence as before. Each negative
number sets off a different sequence.
There is a way of obtaining a more nearly random
sequence of (random' numbers. If the seed given to
the random number generator is different each
time, the sequences will be different. We can get
an unknown, varying seed by using the 64's built in
timet. The preset variable TI (or TIME) is
incremented automatically every 60th of a second.
Ifyou use TI to seed the random number generator
you will obtain a different number every time.
This means that:

will give an unknown seed to the random number
generator .
. To sum up, if the number given to the RND
function is greater than zero, a number from a
sequence of (random' numbers is returned by the
function. If the number given to the function is



negative, a new sequence of random numbers is

Dice Throwing
We can use random numbers in programs to
imitate the throwing of dice. Try this:

A = RND(-TI)
GET K$:IF K$="" THEN 30
DICE = INT( (RND(0)*6) + 1)

This program will throw the die every time you
press a key. Pressing the STOP key will stop the

Commodore BASIC allows you to define functions
of your own, which can be used throughout a
pro gram. Functions are defined by the command
DEF FN. They can then be used like any other
functions in calculations and tests.

DEF FNA(N) = iT * Nt 2
IF FNA(R) < 100000 THEN 30


The Commodore 64 Omnibus - Part 1

This program uses a function FN AREA which is
defined in line 10. The variable N in the definition
is a tdummy' variable - any variable name ean be
used when the function is used later in the
program. The function is used in lines 50 and 60.
The name of a function may be any legal variable
name. It may have any number of letters, but, as
with variables, only the first two charaeters are
notieed by the 64.

There are several built-in functions in Commodore
BASIC whieh operate on numbers or variables:
SQR(N) ealeulates the square root of a number N.
ABS(N) returns the absolute value of a number ehanging negative numbers into positive ones, and
leaving positive numbers unehanged.
INT(N) returns the integer value of N, removing
any fraetional part.
SGN(N) gives 1 ifN is positive, 0 ifN is zero and-1
ifN is negative.
The trigonometrie funetions:



return the values for the angle N (which must be in
LOG(N) returns the natural logarithm of a
RND(N) returns a pseudo random number between

o and 1.

RND(-N) will re-seed the random number
DEF FN allows you to define your own functions
wi thin programs.


As well as doing ari thmetic, the Commodore 64 can
perform tests to compare numbers and strings. We
have already seen this when using IF •.. THEN. In
this chapter we will examine in more detail the
way in which the 64 makes comparisons.
Consider the program line:

IF A = 3 THEN 500

The line instructs the 64 to branch to line 500 if the
variable A holds the value 3. What does the 64 do
when it encounters this program line?
The first thing the computer must do is decide
whether A is equal to 3; or to put it another way,
whether tA = 3' is true. The 64 tests this, and if the
expression is true, i t returns an answer of -1; if the
expression is false, the answer is O. If the result is
true (-1), the commands after THEN are obeyed. If
the answer is false (0) the program will continue
with the next line.
Why are we telling you all this? Because the
computer can compare numbers and return true or
false values without IF. Try this short program:

A = 3



The program displays t-1'. If you change line 10 to

Logical Thinking


10 A = 5
the pro gram will print O.

This applies to all the other comparisons listed in
Chapter 5 as condi tions for IF:

Less than


Greater than




Greater than or equal


Less than or equal

Try this:




PRINT A <= 7

If you try out the other tests, you will find they all
behave in the same way.

If two tests are combined, the same true and false
answers are still obtained:

A = 5
PRINT ( A < 7 ) AND ( A > 3 )

Now, if the computer evaluates simple relational
expressions such as A<7, A>3 as -1 or 0, what
happens when two are combined, and what does the
There are three BASIC commands which can be
used with relational expressions: AND, OR and


The Commodore 64 Omnibus - Part 1

NOT. Forgetting about numerical representations
of true and false for the moment, let's look at what
these commands do.
U sing AND to relate two expressions, as in the
example above, it seems fairly obvious that the
final result will be true only if both smaller
expressions are true. This is in fact what happens.
Here is a table of the possible combinations, with
the two simple expressions represented by X and Y.
(This type oftable is called a 'truth table'.)
















Truth Table for AND

The command OR also does the obvious thing,
returning -1 if X or Y or both are true.
















Truth Table for OR

NOT changes from true to false, and vice versa, so:

Logical Thinking



A = 3

prints -1 (true). Here is the truth table for NOT.







Truth Table for NOT

All this is fairly easy to follow. But the 64 is using
numbers to represent true and false. How does it
work out the answers?
To understand this, you must understand how the
computer stores numbers in binary notation
(Appendix 10 contains an explanation). AND,OR
and NOT are actually applied by the 64 to the
binary representations of the numbers. The truth
tables for the three operators remain the same, but
true and false are replaced by 1 and O. The truth
table for AND therefore changes to the form shown
on page 86.
Each number contains more than one binary digit
(or (bit'). The 64 applies AND, OR and NOT to the
numbers by comparing bits at the same place in
each number. Suppose A and B were two 4-bit


So. which is O. This means that -1 is stored as 1111. so the AND. we can now see why the numbers 0 and -1 are used. we find AANDB = 1000 By similar means we can show that ifP is 1010 and Q is 0011.86 The Commodore 64 Omnibus . Bit 2 is 0 AND 0 which is also O.Part 1 A B AANDB 1 1 1 1 0 0 0 1 0 0 0 0 Numerical Truth Table far AND The digits for (A AND B) are found by comparing the corresponding digits of A and B. P OR Q is 1011. and false is all zeros. To represent negative numbers the machine uses the two's complement system. and ifZ is 0101. . Returning to the computer's comparisons of true and false. bit 1 of A AND B (counting from the right) is (0 AND 1). This means that true is a number which is all ones. while 0 is stored as 0000 (the computer actually uses 16 bits to represent each. but it's easier to follow with only 4). NOT Z is 1010. OR and NOT commands can work on the individual bits and produce the right answer. Proceeding thus.

320 330 IF (A+B»6 THEN Z=7 IF (A+B)<=6 THEN Z=O could be replaced by the single line: 320 Z = -((A+B»6)*7 and the two lines: 500 510 IF P=Q THEN T=5 IF P<>Q THEN T=3 are equivalent to: 500 T = 3-2*(P=Q) AND can be used to keep numbers within certain limits by masking. The four highest bits of the result (the left four) would be zero. because 0 AND X is always O. The four lower bits would be the same as those of the other number. For example: 10101010 AND 00001111 = 00001010 We can therefore use AND to copy only apart of a number. but it can be used to simplify some pro grams which involve tests. Look at this example: 230 240 A = A + 1 IF A > 15 THEN A = 0 15 in binary is 00001111. If A is increased to 16 (00010000) then A AND 15 will be O. Think about what would happen if any binary number was ANDed with the number 00001111. whatever the other number.Logical Thinking 87 It may seem that all this knowledge is of little use when programming in BASIC. We could replace the two program lines with 230 A = (A+1) AND 15 .

Relational tests such as those performed after IF are represented numerically: True is represented by the number -l. which means that in a long program. but they are also faster. SUMMARY The Commodore 64 can not only handle numerical calculations: it can solve logical problems too. OR A OR B is true if either Ais true or Bis true or both are true. . NOT NOT A is true if Ais false. considerable time savings can be made. False is represented by the number O.Part 1 These uses of relations and logical operators may seem more confusing than using IF to perform tests. or one which willloop many times. There are three logical operators: AND A AND B is true if both A and Bare true.88 The Commodore 64 Omnibus .

so the memory locations of the 64 hold one byte of da ta each. What happens to the others? The first lk of memory is used as a storage area by the machine code pro grams that interpret your BASIC pro grams and operate the machine.1 byte for every character. and location has a unique reference number called its address. Larger numbers need more than one location. and all the memory up to 40k is free for BASIC pro grams and . which can have a value between 0 and 255. In a microcomputer like the Commodore 64. each of which can hold one number. You will have noticed that the message displayed when you switch on the computer announces that 38911 bytes are free for use by BASIC programs. locations 55296 to 56295. Each storage unit is called a memory IDeation.CHAPTER 10 MEMORY MANAGEMENT The memory of a computer is buHt up from a large n umber of storage uni ts. or 64k). they are explained in Appendix 10. A second block of memory. (If you are not sure about binary numbers.) Eight bits of storage are called a byte in computer jargon. The next 1000 bytes are used to store the display picture . The microprocessor used in the Commodore 64 (the 6510) is able to make use of 65535 memory locations (65535 is 2 16 . BASIC programs begin at loeation 2048. holds the colour data for each character. each memory location can hold an eight-bit binary number.

POKE and PEEK. or ROM. which are used to look at individual memory locations. The second puts the code for white in the corresponding position in the colour memory (these will be explained in the next chapter). and is used to store the pro grams needed for the computer to work at all. Clear the screen.90 The Commodore 64 Omnibus . and type: POKE 1024. There are two types ofmemory used in a computer. move the cursor down 1 line. telling you that the number in location 1024 is a 1 (it should be.Part 1 variables. PEEK is used to find out the contents of a location. and POKE writes a new number into the memory. If you now type: PRINT PEEK(1024) the computer will print the answer 1. as you'vejust put it there!). the BASIC interpreter for example. You should see a white A at the top ofthe screen. cannot be altered. and its contents can be changed as the data changes. Read only memory. Random access memory. 1 POKE 55296. What makes the POKE and PEEK commands so important is that not all the memory addresses of the 64 are used for memory. The remainder of the memory contains the routines that operate the computer and run BASIC programs. 1 The first POKE puts the code for an A in the first position ofthe screen. Some of the addresses are used to point to the control registers of the . There are two BASIC commands. You can try out PEEK and POKE by using them to control the display. is used to store data. or RAM.

so use the formula: PRINT FRE(X) + 65535 The argument of the function has no effect . which manages the sound and music facilities ofthe 64.any number or variable can be used. Enter a program. If the amount free is greater than 32767. The function FRE(X) tells you how much memory is left unused. you will find that even the 38k ofprogram space provided by the 64 is not unlimi ted. and also the Sound Interface Device. This me ans that the chips can be controlled simply by writing a number into these control registers using the POKE command. EMPTY SPACE As you write longer programs. These locations are two ofthe registers ofthe Video Interface Chip. If you RUN the program and use FRE(X) a third time the number printed will be smaller still. . or VIC. as the 64 has taken memory space to store the variables. If a pro gram uses large arrays for data storage.Memory Management 91 special chips which control the sound and graphics facilities. and a smaller number will be printed. In the following chapters we will describe how to use the VIC. the memory can be eaten up at an alarming rate. and try it again. which provides all the display functions of the Commodore 64. You discovered in Chapter 3 that the screen and border colours could be changed by POKEing numbers into locations 53280 and 53281. or SID. Ir you check the memory immediately after switching on your 64. FRE(X) will return a negative number. the free space will be 38908 bytes.

but leaves the program itself intact. CLR also resets the variable pointers.Part 1 THE CLR COMMAND The CLR command may occasionally be useful. and should therefore be used after moving the top of BASIC memory by POKEing new values into locations 55 and 56. You can then start a pro gram with the maximum amount of memory free.92 The Commodore 64 Omnibus . The command clears all the variables stored by a program. . This technique is used in Chapter 12 to protect relocated character sets from BASIC programs.

The 64 has no built-in loudspeaker. a range of eight octaves. and can also be played through a hi -fi system.PART 1 The Commodore 64 has exceptional sound generating facilities. The built-in Sound Interface Device (SID) is a synthesiser on a chip. WHAT IS SOUND? Sound is the effect on our ears of vibrations in the air caused by a vibrating object such as a guitar string or a loudspeaker. with three voices. and even to mix sound generated by the 64 with sound fed in from an external source. Vibrating Guitar String . It is possible to filter the sound. but uses the loudspeaker of the television or moni tor to which i t is connected. and extensive control of the waveforms and envelopes of each voice.CHAPTER 11 SOUND AND MUSIC .

and the amplitude determines the volume. and this wave-shape. or waveform. High and Low Frequencies Large and Small Amplitudes (Loud and Soft) Not all sounds have the same shape of wave.94 The Commodore 64 Omnibus . What you hear depends on the properties of the wave: the rate at which the object vibrates (the frequency of the vibration) determines the pitch of the sound. The Commodore 64 can . has a great efTect on the quality of the sound.Part 1 If we plot a graph of the way a vibrating object moves over time we get an undulating shape which Time Amplitude Simple Wave is called a (wave'.

Sound and Music . Sustain and Release. and Release describes the rate at which the sound falls off to nothing. Sustain is the volume at which the sound steadies. Attack is the rate at which the sound rises from nothing to full volume when the note begins. The diagram on the next page shows the envelope properties. Decay is the rate of falling off to a steady volume. which are shown in the diagrams: ~~ Triangle Waveform Sawtooth Waveform 1 1 Pulse Waveform ~F ~ Noise Waveform The final property of sounds which can alter the way we hear them is the variation of the volume over time. Four parameters are used to describe the shape of the 'envelope' of the sound wave: Attack. Decay.Part 1 95 generate four different waveforms. .

17 SET VOLUME .Part 1 96 v o I u m e ..-. Attack . 37 54273.. the sound has to be controlled by POKE commands direct to the SID chip. There are a further eight registers which control the volume of the three voices together.. These control the frequency of the generated note. The registers controlling the first voice are at memory locations 54272 to 54278.. This is not as difficult as it seems.----... Try this program to see how these registers are used (don't bother to type in all the REM lines): 10 20 100 110 120 200 REM REM REM POKE POKE REM FIRST SOUND PROGRAM USES VOICE 1 ONLY SET FREQUENCY 54272.... but it does make programs using sound look confusing. . its waveform and the envelope shape of the sound..The Commodore 64 Omnibus ....... . Each of the three voices is controlled by seven registers of the SID chip.-. Decay Sustain Release The Envelope Parameters USING THE SOUND GENERATOR Because the Commodore BASIC does not support special commands to do the job... and the filter which may be used to modify the sound once i t has been defined.

CONTROLLING THE SID CHIP The registers of the SIn chip controlling the three voices are as follows: Voice 1 Voice 2 Voice 3 No.Low Byte 54273 54280 54287 1 Frequency .168 REM TURN ON THE SOUND WITH SAWTOOTH WAVEFORM POKE 54276.Part 1 210 300 310 320 400 410 500 510 600 610 620 97 POKE 54296.High Byte 54274 54281 54288 2 Pulse Waveform Properties . Property Controlled 54272 54279 54286 0 Frequency .High Byte 54276 54283 54290 4 Control RegisterWaveform and On/Off 54277 54284 54291 5 Attack and Decay 54278 54285 54292 6 Sustain and Release .Low Byte 54275 54282 54289 3 Pulse Waveform Properties . 32 POKE 54296.54 POKE 54278. 33 REM WAIT A WEILE FOR T = 1 TO 500 : NEXT T REM SWITCH OFF SOUND POKE 54276. 0 When you RUN the program you should hear a note from the loudspeaker of your television (make sure the volume control is not turned right down). 15 REM SET ATTACK/DECAY & SUSTAIN/RELEASE POKE 54277.Sound and Music .

the higher the number the higher the note. F . F/256 GOTO 100 Try entering different frequency numbers and see how the sound changes.06 (beats/second) There is no need for complex calculations to work out notes as there is a table on page 152 of the Commodore 64 User Manual which gives the numbers for all notes over a range of8 octaves. The frequency heard relates to the number in the registers like this: Frequency = Number * 0.Part 1 98 Registers 0 and 1 (which are locations 54272 and 54273 for Voice 1. F POKE will need it again . The frequency used in the previous pro gram gave the note middle C. Register 4 selects the waveform to be used. 105 110 120 1000 INPUT "FREQUENCY NUMBER".The Commodore 64 Omnibus . The possible values are: 17 33 65 129 Triangle Sawtooth Pulse Noise To see in more detail how these registers are used we will use the previous program to test the effects of altering the parameters ofthe sound.INT(F/256)*256 POKE 54273. and the highest possible note . You won't hear much für values of less than abüut 500. FREQUENCY Save the program onto tape .and then change the pro gram by typing in the following alterations. for example) control the frequency of the sound.

This is done by specifying the width ofthe peak as a proportion ofthe whole cycle. and RUN the program. alter line 410 to: 410 POKE 54276. To stop the program hold down RUN/STOP and tap RESTORE. Notice the effect of doubling the number.Sound and Music .F It is possible to alter the proportions of the wave by altering the width of the peaks. modify the pro gram again by typing: 410 POKE 54276. is slightly more complicated than the others. type in these newlines: 50 105 510 550 F = 250 F = F * 2t(1/12) FOR T = 1 TO 50 : NEXT IF F < 61800 THEN 105 Delete line 1000. 5000. To hear the Triangle waveform. To hear the full range of frequencies. WAVEFORMS The pro gram uses the Sawtooth waveform which gives a slightly buzzy tone. The proportion is set . 6000. 8000. to produce a variety of alternative waveforms.. Pulse.. You will remember that the waveform is: --. 17 To hear the Noise waveform. or of increasing it by 1/2. Try the sequence 4000.Part 1 99 is 65535.. 129 The fourth waveform.

350 360 370 380 390 410 610 1000 REM SET PULSE WIDTH INPUT "PULSE WIDTH %".The Commodore 64 Omnibus .95 POKE 54274. P P = P*40. reload the first pro gram and make the following changes. giving: ~F I Pulse Width = 2047 (50%) To try out the pulse waveform. 65 POKE 54276.Part 1 100 1 1 LJ ~ LJ Alternative Pulse Waveforms by POKEing a number between 0 and 4095 into registers 2 and 3 for the voice concerned (locations 54274 and 54275 for Voice 1). P AND 255 POKE 54275. A value of 0 or 4095 would give a straight line: Pulse width 4095 Pulse width 0 A value of 2047 would make the peak width 50% of the total. P/256 POKE 54276. 64 GOTO 360 .

which gives the balanced waveform with equal high and low times. Reload the first program again and type these lines: 210 220 1000 INPUT "VOLUME". V POKE 54296. A INPUT "DECAY". Type in the modifications below: 310 320 330 340 350 360 510 620 INPUT "ATTACK". VOLUME The volume of the the sound of all three voices is controlled by location 54296. V GOTO 210 ENVELOPE The final way of altering the sound of a voice channel is by altering the Envelope. D INPUT "SUSTAIN". The smoothest tone is given by a value of 50. «A AND 15) * 16) OR (D AND 15) POKE 54278. S INPUT "RELEASE". For the last time.Part 1 101 The program requires inputs between 0 and 100. As the numbers increase or decrease from 50. or volume profile.Sound and Music . reload the first program. representing the pulse width as a percentage of the total. Try a few different values. Decay. the sound becomes sharper and more ttinny'. This is done wi th the four parameters Attack. Sustain and Release. ( (S AND 15) * 16) OR (R AND 15) FOR T = 1 TO 500: NEXT T GOTO 310 . The possible values are from 0 to 15. with 0 giving no sound and 15 maximum volume. R POKE 54277.

The durations of Attack.102 The Commodore 64 Omnibus . the four least significant bits control Decay. Decay and Release . with Sustain controlled by the most significant bits.5 s 2.Part 1 Attack and Decay are controlled by register 5 for each voice (54277 for Voice 1). The value used for Sustain controls the volume of the note after the Attack and Decay phases.4s 3s 9s 15 s 24s 6ms 24ms 48ms 72 ms 114 ms 168 ms 204ms 240 ms 300 ms 750 ms 1.4s 3s 9s 15s 24s Attack. Sustain and Release are similarly controlled by register 6 for each voice (for Voice 1 it's 54278). Each of the four variables can have a value from 0 to 15. RUN the program and experiment to find the effects of different envelope parameters.5 s 2. The four most significant bits of the register control Attack. Decay and Release for the range ofvalues which can be set are shown below: VALUE ATTACK DECAY RELEASE 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 2 ms 8ms 16 ms 24 ms 38 ms 56 ms 68 ms 80 ms 100 ms 250 ms 500 ms 800 ms 1s 3s 5s 8s 6ms 24 ms 48 ms 72 ms 114 ms 168 ms 204ms 240 ms 300ms 750 ms 1.

Two filters may be eombined to produee more eomplex filtering. Three different filters may be used. The filters are seleeted by bits 4. You will remember that this is the loeation .Sound and Music . and a 100% 0% Frequency Low-Pass Filter Band-pass filter whieh allows only the frequencies 100% 0% Frequency Band-Pass Filter within a limited range to pass. a Low-pass filter whieh suppresses high frequencies. 5 and 6 of loeation 54296. The three are a High-pass filter. The filter is eontrolled by the four registers 54293 to 54296. the SID ehip has a built-in filtering faeility whieh filters the output from all three voiee ehannels together. either singly or in eombination.Part 1 103 FILTERING In addition to the three voiees. 100% 0% Frequency High-Pass Filter whieh allows high frequeney sounds to be output but suppresses the lower frequencies.

There .Part 1 104 controlling the volume. only the lower four bits of the register are needed to hold the volume setting. but as the volume can only vary between 0 and 15. 100% 0% I ~-----------------------------Frequency High-Pass and Low-Pass Filters Combined 100% 0% I J ~-------------~---------------------- Frequency High-Pass and Band-Pass Filters Combined BIT MEANING VALUE 0-3 Volume 0-15 4 Low Pass Filter 16 5 Band Pass Filter 32 6 High Pass Filter 64 7 Turn off Voice 3 128 Setting Filters .Location 54296 So. to select the High pass filter and a volume of 7.The Commodore 64 Omnibus . The full details of the use of location 54296 are shown in the table. which is 71. the register must be POKEd with a value of 64 + 7. The cut-off frequency of the filter is controlled by the registers at locations 54293 and 54294.

the lowest 3 bits of 54293 hold the 3 least significant bits of the frequency. while the eight most significant bits are held in 54294.Part 1 105 are 11 bits altogether for the frequency setting. the sharper is the filter cut-off ofthe unwanted frequencies. The higher the number. BIT MEANING VALUE 0 Filter Voice 1 1 1 Filter Voice 2 2 2 Filter Voice 3 4 3 Filter External Signal 8 4-7 Resonance 16 . \ Low and High Resonanee Filters THE CONTROL REGISTER The control register (register 4 for each voice. .240 Seleeting Filters . Location 54295 is used for two purposes: to select which of the three voices are to be filtered.Loeation 54295 The resonance value controls the sharpness of the cut-off. Each of the eight bits ofthe register has a differentmeaning. and to set a resonance value.Sound and Music . location 54276 for Voice 1) does more than control the waveform used by the voice.

When GATE is set i-l. Only one of these bits should be set to '1' at any time. The note is sustained until GATE is set to 0.106 The Commodore 64 Omnibus . or the sound will be cut om. siren effects can be achieved. These are described below. TEST switches off the oscillator if bit 3 is set to 1. By varying the frequency while a note is playing. It is important not to alter the waveform when clearing GATE. This is oflittle use in sound generation. SOUND EFFECTS The SID chip can not only be used for playing music. but for producing all kinds of sound effects and strange noises. RING MOD and SYNC allow the production of more complex waveforms than the standard waveforms available. The SID chip has extra facilities for producing more complex sounds than those we have heard so . It is possible to alter the waveform while a note is playing by setting the appropriate bits of the control register (remember not to clear the GATE bit of the register. the Attack/Decay/Sustain cycle starts.J 1. when the Release phase of the note be gins.Part 1 BIT7 BIT6 BITS BIT4 BIT3 BIT2 BIT 1 BITO Noise Pulse 128 64 TriSawtooth angle 32 16 Test Ring Mod Sync Gate 8 4 2 1 The Voice Control Register The four most significant bits ofthe register control the waveform of the voice. or the ~ound will change during the Release phase. The GATE bit turns the sound on and off.

these are accessed by using the RING MOD and SYNC bits ofthe voice control registers. If the frequency of Voice 3 is greater than that of Voice 1 similar effects result.. The waveform of the synchronised voice can be set to any one of the four possibili ties. ·· . then if Voice 1 is synchronised with Voice 3 the output will look like: That is. SYNC The SYNC bit of the control register of each voice synchronises the output of the voice with the frequency of one of the other voices./'.. ·· :~ ~--------~ Voice 3 Frequency and Voice 3 has the frequency indicated. /'. as shown overleaf. . though best . ..Part 1 107 far..Sound and Music . If Voice 1 is producing a triangle wave like this: · .. The voices are paired thus: Voice 1 is synchronised wi th V oice 3 Voice 2 is synchronised wi th V oice 1 Voice 3 is synchronised wi th V oice 2 The SYNC function controls the waveform of the voice by repeatedly restarting the wave at the frequency of the controlling voice. ~........ the waveform becomes arepetition of part of the Voice 1 waveform at the frequency ofVoice 3..

N otice tha t when the frequency is equal to that of Voice 3. V3 POKE 54277. 84 POKE 54278. VI V3=35 FOR 8=54272 TO 54296: POKE 8. 84 POKE 54291. The use of SYNC can produce many new waveforms of great tonal interest as the two frequencies are varied with respect to each other. 15 POKE 54273. 0 POKE 54290. The properties of the synchronising voice other than its frequency have no effect at all on the sound produced. the sound is unaltered. 19 FOR 8=1 TO 1000: NEXT POKE 54276. and when the Voice 1 frequency is a multiple or a factor of the Voice 3 frequency the sound is less interesting. 0 GOTO 10 Try altering the frequency of V oice 1. 10 20 30 40 50 60 70 80 90 100 110 120 200 210 500 INPUT"VOICE 1" . VI POKE 54287. . 168 POKE 54292. Best results are achieved when the frequencies are elose to each other.0: NEXT POKE 54296.Part 1 108 results are obtained from the triangle and sawtooth waveforms.The Commodore 64 Omnibus . The following program will allow you to try out different combinations of frequencies in the two voices. 168 POKE 54276.

21 Note again that for best results the two frequencies should be elose to eaeh other but not identieal. To use ring modulation.Part 1 109 RING MODULATION If bit 3 of a voiee eontrol register is set. the output ofthe voiee is ring modulated with the frequeney of one of the other voiees. have no effeet. OTHER SID REGISTERS There are four registers on the SID ehip whieh have not yet been mentioned. resulting in a nonharmonie mixture of frequencies. and neither should be a multiple ofthe other.The Voice Pairings Try out the effeet ofsetting RING MOD by altering the SYNC program thus: 110 POKE 54276. These are: 54297 54298 54299 54300 POTX POTY OSC 3 ENV3 . other than its frequeney. the tri angle waveform must be used for the voiee to be modulated.Sound and Music . The properties of the modulating voiee. the voiees pair thus: MODULATED VOICE MODULATING FREQUENCY Voice 1 Voice 3 Voice 2 Voice 1 Voice 3 Voice 2 Ring Modulation . As for SYNC.

The effects can be made much more dramatic by using OSC 3 to control the high byte of the Voice 1 frequency. 32 or 128. These registers can be used to modify the volume of the SID. 33 POKE 54290. by altering the numberPOKEd into 54290 in line 120 to 16. modify the SYNC program by deleting lines 10. 35 POKE 54287. Try altering the waveform. 20 and 500.Part 1 110 POT X and POT Y are used with games paddles. 0 POKE 54273. PEEK(54299) GET K$: IF K$="" THEN 130 The program uses the level of Voice 3. to alter the frequency of Voice 1.The Commodore 64 Omnibus . As it is written. 170 POKE 54292. read from 54299. 3 POKE 54276. 64 POKE 54272. and modi fies the low byte of the Voice 1 frequency. Alter line 130 to: 130 POKE 54273. and have no application to music. the pro gram uses the Pulse waveform in Voice 3. or the frequency of one of the voices. PEEK(54299) The effect of using a noise waveform for Voice 3 is worth hearing! To hear the effect of using ENV 3. make these modifications to the program: 80 100 130 POKE 54291. PEEK(54300) Here the envelope of Voice 3 is used to control the high byte of the frequency of Voice 1. The Attack . OSC 3 holds the level of the output signal from Voice 3. and ENV 3 contains the volume of Voice 3 as modified by the envelope. To test the effects of this. and adding the following lines: 50 60 110 120 130 140 POKE 54273.

MAKING MUSIC Now that we have dealt with the theory of Commodore 64 sound generation.Part 1 111 and Decay values for Voice 3 are initially set to 10. You will find that values below 8 for Attack and Decay are too fast for the effect to be noticeable. The values of Attack and Decay can be controlled by altering line 80. and Release therefore has no effect.1) READ K lF K = 0 THEN 1100 READ N(K. We have now dealt with all the functions ofthe SID chip. The table in Appendix 13 summarises the functions of all the registers. The first and most obvious use ofthe synthesiser chip is as a synthesiser. The example program below turns your 64 into an electronic organ.Sound and Music .O).l) GOTO 1010 . N(K. giving you full control over the waveforms of the voices and the filtering: 10 20 30 40 50 60 ******************* *** *** *** SYNTHESlSER *** *** *** ******************* 70 REM REM REM REM REM REM REM 990 992 994 996 REM ********************* REM * SET UP NOTE TABLE * REM ********************* REM 1000 1010 1020 1030 1040 DlM N(255. Sustain is set to zero. we will look at the practical applications ofthe SID chip.

0: ENO 2010 2020 2030 2100 2110 2120 2130 2140 2150 2160 . 0: NEXT SIO = 54272 VOL = 6 FOR VV=l TO 3: F$(VV)="N": NEXT 1110 1120 1130 1990 1992 1994 1996 1998 REM REM ************** REM * FIRST MENU * REM ************** REM 2000 PRINT "{CLS}{CO}{CO}" TAB(15) "{RVS} SYNTHESISER {ROF}" PRINT: PRINT: PRINT" VOICE {RVS}1{ROF}/{RVS}2{ROF}/{RVS}3 {ROF}" PRINT: PRINT: PRINT" FILTER {RVS}F{ROF}" PRINT: PRINT: PRINT" PLAY {RVS}P{ROF}" GET K$: IF K$ = "" THEN 2100 IF K$="F" THEN GOSUB 3000: GOT02000 IF K$="l"THEN VV=l: V=O: GOSUB 2500: GOTO 2000 IF K$="2"THEN VV=2: V=7: GOSUB 2500: GOTO 2000 IF K$="3"THEN VV=3: V=14: GOSUB 2500: GOTO 2000 IF K$ = "P" THEN PRINT "{CLS}": GOSUB 5000: GOTO 2000 IF K$ = "{F8}" THEN POKE S+24.Part 1 1090 1092 1094 1096 1098 REM REM *********************** REM * CLEAR SIO REGISTERS * REM *********************** REM 1100 FOR L = 54272 TO 54296: POKE L.112 The Commodore 64 Omnibus .

PRINT TAB(20) "WAS" W$(VV) PRINT: PRINT "WAVEFORM:" TAB(10) "{RVS}S{ROF}AWTOOTH" PRINT TAB(10) "{RVS}T{ROF}RIANGLE" PRINT TAB(10) "{RVS}P{ROF}ULSE" PRINT TAB(10) "{RVS}N{ROF}OISE" GET K$: IF K$ = "" THEN 2600 IF K$ = "S" THEN W(VV) = 32: W$(VV) = "{RVS}SAWTOOTH": GOTO 2800 IF K$ = "T" THEN W(VV) = 16: W$(VV) = "{RVS}TRIANGLE": GOTO 2800 IF K$ = "N" THEN W(VV) = 128: W$(VV) = "{RVS}NOISE": GOTO 2800 IF K$ <> "P" THEN 2600 W$(VV) = "{RVS}PULSE" PRINT: PRINT TAB(5) W$(VV): PRINT W(VV) = 64 P = P(VV) PRINT "PULSE % (WAS" P(VV) ")".: GOTO 2710 P(VV) = P 2510 2520 2530 2540 2550 2560 2600 2610 2620 2630 2640 2650 2700 2710 2720 2730 2740 2750 .Part 1 113 2200 GOTO 2100 2490 2492 2494 2496 2498 REM REM ************************ REM * SET VOICE PROPERTIES * REM ************************ REM 2500 PRINT "{CLS}{CD}{CD}" TAB(12) "{RVS} VOICE PROPERTIES {ROF}" PRINT: PRINT "VOICE"VV.: INPUT P IF P < 0 OR P > 100 THEN PRINT "{CU}".Sound and Music .

: INPUT F$(VV) IF F$(VV)="Y" THEN RF=RF OR (2t(VV.A+D POKE SID+V+6.: INPUT S(VV): S=(S(VV) AND 15)*16 PRINT "RELEASE (WAS" R(VV) ")".: INPUT A ( VV): A = (A(VV) AND 15)*16 PRINT "DECAY (WAS" D( VV) " ) " .: INPUT D ( VV): D = (D(VV) AND 15) PRINT "SUSTAIN (WAS" S(VV) ")". (P AND 255) POKE SID+V+3.S+R PRINT"{CD}FILTER {RVS}Y{ROF}/{RVS}N{ROF} (WAS " F$(VV) " )".The Commodore 64 Omnibus .RF RETURN 2990 2992 2994 2996 2998 REM REM ************************* REM * SET FILTER PROPERTIES * REM ************************* REM 3000 PRINT "{CLS}{CD}{CD}" TAB(12) "{RVS}FILTER PROPERTIES" 2810 2820 2830 2840 2850 2860 2870 2880 2890 .1»:GOT02910 IF F$ (VV) < > "N" THEN PRINT"{CU}{CU}{CU}":GOTO 2870 RF=RF AND (255-2t(VV-1» POKE SID+23. INT(P/256) GOTO 2810 PRINT: PRINT TAB(5) W$(VV): PRINT PRINT "ATTACK (WAS" A ( VV) " ) " .Part 1 114 2760 2770 2780 2790 2800 2900 2910 2950 P = P(VV)*40.: INPUT R(VV): R=(R AND 15) POKE SID+V+5.95 POKE SID+V+2.

Part 1 3010 115 3160 3170 3500 PRINT: PRINT "HIGH PASS {RVS}Y{ROF}/{RVS}N{ROF} (WAS "HP$" )"i: INPUT HP$ VOL = VOL AND 191 IF HP$="Y" THEN VOL=VOL OR 64 PRINT: PRINT "BAND PASS {RVS}Y{ROF}/{RVS}N{ROF} (WAS "BP$" )"i: INPUT BP$ VOL=VOL AND 223 IF BP$="Y"THENVOL=VOL OR 32 PRINT: PRINT "LOW PASS {RVS}Y{ROF}/{RVS}N{ROF} (WAS "LP$" )"i:INPUT LP$ VOL = VOL AND 239 IF LP$="Y" THEN VOL=VOL OR 16 PRINT: PRINT "FILTER FREQUENCY (WAS" FQ " )"i: INPUT FQ IF FQ > 2048 OR FQ < 0 THEN PRINT "{CU}{CU}{CU}": GOTO 3100 POKE SID+21.Sound and Music .FQ AND 7 POKE SID+22.(RF AND 15) OR 16*RS RETURN 4990 4992 4994 4996 4998 REM REM REM REM REM 5000 PRINT "{HOM} {CD} {CD}" TAB(18) "RPLAY" PRINT "{HOM}{CD}{CD}{CD}{CD}{CD}{CD} {CD} PLAYING VOICE" VV PRINT "{CD}{CD}{CD}{CD}{CD} {RVS}Fl{ROF} VOICE I" 3020 3030 3040 3050 3060 3070 3080 3090 3100 3110 3120 3130 3150 5010 5020 ******** * PLAY * ******** .INT(FQ/8) PRINT: PRINT"RESONANCE (WAS" RS " )"i: INPUT RS IF RS < 0 OR RS > 15 THEN 3150 POKE S+23.

9.10 . W(VV): VV=2: V=7: GOTO 5010 IF K$="{F5}" THEN POKE SID+V+4. 52.104. HI POKE SID+V.247.Part 1 116 5030 5040 5050 5060 5070 5080 5090 5100 5110 5120 5130 5140 5150 5160 5170 5180 5190 5200 5210 5300 5310 5320 5400 5500 PRINT: PRINT " {RVS}F3{ROF} VOICE 2" PRINT: PRINT " {RVS}F5{ROF} VOICE 3" POKE SID+24. W(VV): VV=3: V=14: GOTO 5010 IF K$=CHR$(13) THEN POKE SID+24. 51.8 60010 DATA 69.233. W(VV) POKE SID+V+l. 82.VOL PRINT "{HOM}{CD}{CD}{CD}{CD} VOLUME"VOL AND 15"{CL} " GET K$: IF K$="" THEN 5070 HI=N(ASC(K$).143.97.8. 0: RETURN GOTO 5070 60000 DATA 81.7.O) POKE SID+V+4.9. 87.l) IF HI=O THEN 5150 POKE SID+V+4.225. N(ASC(K$). W(VV): VV=l: V=O: GOTO 5010 IF K$="{F3}" THEN POKE SID+V+4.The Commodore 64 Omnibus . W(VV)+l GOTO 5070 VX=VOL AND 15 IF K$ <> "{CU}" THEN 5180 IF VX < 15 THEN VX = VX+l: GOTO 5200 IF K$ <> "{CD}"THEN 5300 IF VX > 0 THEN VX = VX-l VOL = (VOL AND 240) OR VX GOTO 5050 IF K$="{Fl}" THEN POKE SID+V+4.

as a quick response to the keyboard is essential in this application.239.31.THEN test.1) by lines 1000 to 1040. The diagram overleaf shows the relation of the 64 keyboard to the organ keyboard.209. 89. but it has the advantage of speed.181. 54. so that you can experiment with different tones.11.14 60040 DATA 73. The top two rows of the 64's keyboard are used as the <organ' keyboard.156. 94. 49. The data is loaded into the array N(255.239. 85.. 79. corresponding to the ASCII codes of the keys (not all of which are used).210.78.c .28 60080 DATA 95.15. This use of an array is wasteful of memory. The information relating the keys to the notes is held in the DATA statements at the end of the program (lines 60000-60100).26.119. 43.48. The array has 255 elements.14. to see if the key pressed was a valid one.218.30. The first menu page is controlled by the .22.18. 56. This allows the note to be played after only one IF . about lK of memory is reserved for the array and not used.19.24. 92.21 60060 DATA 42. 20. Lines 1100 to 1130 initialise the pro gram variables. 60100 DATA 0 The program gives you control over the settings of the three voices and the filter.25 60070 DATA 1 117 60020 DATA 84.195.11. 48.12 60030 DATA 55.16.Sound and Mus.12..49.17 60050 DATA 80. 64. The method of processing the key strokes and turning them into notes uses a two dimensional array to hold the values of the high and low frequency bytes of each note.

or keep the existing settings by simply pressing RETURN. setting the filter or playing a tune. Pressing F8 (the SHIFT key and function key 7) will end the program. You will find more about making music with the the SID chip in Chapter 23. The program offers the choice between alte ring the properties of a voice. F3 and F5. Y ou must of course set a voice before trying to play anything.Part 1 118 3 +- 4 Q WER 6 T 7 Y 8 U + 0 I 0 P {HOME @ .Cursor Up for louder. Lines 2500 to 2950 give you control over the properties of the three voices. Cursor Down for softer. The top two rows of the keyboard act as the synthesiser keyboard. The routine in lines 5000 to 5500 handles the playing of notes. .. f DEL lines from 2000 onward.The Commodore 64 Omnibus . Lines 3000 to 3500 allow you to set up the filter in a similar manner. You may enter new settings. The volume is controlled by the Cursor Up and Down key . You can switch between voices using the function keys Fl.

The program should print a smiling face. Shifted characters are represented by {X}. Try this short pro gram. These characters can be obtained by holding down either a SHIFT key and pressing the character key to obtain the righthand symbol of the two shown on the face of the key. The screen displays of the Commodore 64 are stored in the memory ofthe machine as a block of 1000 memory locations. characters requiring the Commodore key are shown as [X]. each holding a number which indicates the character at the corresponding point on the . or by holding down the Commodore logo key and pressing the character key to obtain the lefthand symbol of the two.CHAPTER 12 CHARACTER GRAPHICS The simplest way to produce graphics displays on the Commodore 64 is to use the special characters available from the keyboard. The symbol ois used to represent aspace: 10 20 30 40 50 60 PRINT" {o}[ YYYYY]{ p} PRINT" [H] {W}ooo{W} [N] PR I NT" [H] 00 { Q} 0 0 [ N ] PRINT" [H] 0 0 0 0 0 [N] PRINT"{M}o{J*K}o[N] PRINT" 0 {M}[ PPP ]{N} CHARACTERS AND NUMBERS In Chapter 7 the ASCII code for representing characters by numbers was introduced. You can produce simple but effective displays by using these symbols and the cursor control characters in PRINT commands.

The numbers for the colours are shown in the table below. the other for upper and lower case displays. In normal use. by POKEing the character number into screen memory. while the colour memory extends from location 55296 to 56295.120 The Commodore 64 Omnibus . holds information on the colour of each character.or 'maps' . This method of storing the display data is called 'memory mapping'. This method of controlling the display gives you better control over the positioning of the symbols on the screen than the . and are shown again in the table opposi te and in Appendix 8. as the ASCII character set includes control characters such as the cursor characters while the screen character set uses all 256 numbers to represent displayable symbols. A second area of memory. Using this information you can display characters on the screen without using PRINT. The numbers are the same as those given in Chapter 3 for the background and border colours. For example: POKE 1024. also of 1000 locations. The two character sets and their numbering systems are shown in the table in Appendix 16. There are two sequences of characters. the screen memory of the Commodore 64 is in store locations 1024 to 2023.of the screen memory areas in Appendix 17) The numbers used to indicate the characters on the screen are not the same as those used by the CHR$ command described in Chapter 7. one for displaying upper case letters ancl graphics. 1 would displaya white exclamation mark at the top left corner ofthe screen. as the screen memory area acts as a map ofthe display.Part 1 screen. (There are diagrams . and POKEing a number into the corresponding location of the colour memory. 33: POKE 55296.

11: POKE 53281. You have ten attempts to find out the secret code which the 64 generates.Character Graphics 121 PRINT command. *************** * * * CODEBREAKER * * * *************** 1 2 3 4 5 6 REM REM REM REM REM REM 7 CM=55296: SM=1024 POKE 53280. CODE COLOUR CODE COLOUR 0 Black 8 Orange 1 White 9 Brown 2 Red 10 Light Red 3 Cyan 11 Dark Grey 4 Purpie 12 Mid Grey 5 Green 13 Light Green 6 Blue 14 Light Blue 7 Yellow 1S Light Grey The C%ur Codes CODEBREAKER This program plays the weIl known game. Simple character graphics are used to create the display. guided by the clues which the pro gram displays after each attempt. and can make altering a display much faster. 12 10 .


160 G$ = G$+I$ NEXT I 2092 2093 2094 2095 2096 REM REM REM REM REM 1030 1040 2020 2030 2040 2050 ************ * * * SET CODE * * * ************ *************** * * * INPUT GUESS * * * *************** ******************* * * * RIGHT COLOUR * * AND RIGHT PLACE * .l) FOR I=O TO 3 GET I$ IF I$<"l" OR I$>"8" THEN 2030 POKE CM+176+(I*2)+(G*80). VAL(I$)-l POKE SM+176+(I*2)+(G*80).Character Graphics 123 994 995 996 997 998 999 REM REM REM REM REM REM 1000 1010 1020 1050 C$ = "" FOR I=l TO 4 C$ = C$ + RIGHT$( STR$( INT( RND(0)*8)+1).1) NEXT I PRINT "{CLS}{CD}" TAB(14) "{BLU}CODEBREAKER{GRY}": PRINT: PRINT RETURN 1993 1994 1995 1996 1997 1998 1999 REM REM REM REM REM REM REM 2000 2060 2080 2090 GN$ = "INPUT GUESS " + RIGHT$(STR$(GUESS).

I.Part 1 124 2097 2098 2099 REM * * REM ******************* REM 2100 2110 2150 FOR 1=1 TO 4 IF MID$(G$.l) <> MID$(CODE$.l) AND MID$(G$.I+l) CO$ = LEFT$(CO$.The Commodore 64 Omnibus .J+l) NEXT J NEXT I 2293 2294 2295 2296 2297 REM REM **************** REM * * REM * DISPLAY CLUE * REM * * 2120 2130 2140 2230 2240 2250 .J-l) + "9" + MID$(CO$.I.I-l) + "9" + MID$(G$.I.1)<>"9" THEN C2=C2+1: GOTO 2240 GOTO 2260 G$ = LEFT$(G$.l) THEN 2150 Cl = Cl+l G$ = LEFT$(G$.I-l) + "9" + MID$(G$.I.I+l) CO$ = LEFT$(CO$.l) =MID$(CO$.J.I+l) NEXT I 2192 2193 2194 2195 2196 2197 2198 2199 REM REM ******************* REM * * REM * RIGHT COLOUR * REM * BUT WRONG PLACE * REM * * REM ******************* REM 2200 2210 2220 2260 2270 FOR 1=1 TO 4 FOR J=l TO 4 IF MID$(G$.I-l) + "9 11 + MID$(CO$.

l»-l POKE SM+974+(I*2). GETA$: IF A$=nn THEN 2470 IF A$=ny n THEN 100 PRINT n{CLs}n: END 2320 2330 2420 2430 2440 2445 2450 2460 2465 2470 2480 2490 *************** * * * REVEAL CODE * * * *************** Lines 10 to 85 display the instructions with and example. FOR I=l TO 4 POKE CM+974+(I*2).and lines 2310 and 2330 .is obtained by holding down either SHIFT key and pressing Q. 160 NEXT PRINT TAB(27) nANOTHER Y/N?n.Character Graphics 125 2298 2299 REM **************** REM 2300 2310 2340 2350 2360 IF Cl=O THEN 2320 FOR I=l TO Cl: CLUE$= CLUE$ + n{BLK}e{GRy}n: NEXT IF C2=0 THEN 2340 FOR I=lTO C2: CLUE$ = CLUE$ + n{WHI}e{GRy}n: NEXT PRINT TAB(30) CLUE$ n{CD}n IF Cl=4 THEN 2400 Cl=O: C2=0: CLUE$=nn: RETURN 2393 2394 2395 2396 2397 2398 2399 REM REM REM REM REM REM REM 2400 Z$ = n{RVS}{RED} YOU WIN {ROF}n PRINT n THE CODE WAS n. VAL(MID$(C$.I. PRINT n{HOM}{CD}n TAB(13) Z$.) Lines 1000 to 1050 set up a code of four numbers . (The solid circle character in lines 65 and 70 .

CHARACTER DEFINITIONS The shapes of all the displayable characters are defined by numbers held in a special area of memory.that would make things too easy! If you crack the code. or stop the program. The 64 allows you to create new symbols by entering new definitions for the characters to replace those held in memory. After each keypress the appropriate colour code is placed in the colour memory. and the item is set to t9' to indicate that there is no need to check it further.126 The Commodore 64 Omnibus . Lines 2100 to 2150 check for a correct colour in the right place. and a reversed space (character 160) is placed in screen memory. You may then playanother game. The routine at 2300 to 2360 builds up astring CLUE$ containing a black spot for every correct colour in the right place. the routine at 2400 to 2480 lets you know and reveals the code. pressing the keys between 1 and 8. Lines 2200 to 2250 check for an item of the right colour in the wrong place. Every such item in the guess is set to t9' once it has been recorded to avoid considering it more than once. Each number may appear more than once in the code.Part 1 between 1 and 8. or have run out of guesses. Cl is incremented for every such item in the guess. Note that the clue gives no information on the position of the correct items . which correspond to a grid of eight rows. After four consecutive keypresses the guess is checked. You enter your guess in lines 2000 to 2090. each row consisting of eight dots which . and a white spot for every correct colour in the wrong place. Each symbol in the character set is defined by the contents of eight memory locations.

(Eaeh of these dots is ealled a pixel. the seeond set (which begins at 55296) has both upper and lower ease letters. with fewer graphies eharaeters. multiply the code number of the eharaeter by eight. the pixel is displayed in the foreground eolour.Character Graphics 127 may be set to the foreground or the background eolour. There are two sets of 256 eharaeters: this first set includes graphies symbols and upper ease letters. and eaeh bi t of the number in the loeation represents one pixel. The display is buHt up from 64000 of these pixels. To find the eight bytes defining any eharaeter. whieh is 0 1 2 Memory Location: 3 4 5 6 7 Bit: 7 6 543 2 1 0 The Character Grid a eontraction of picture element.) Eaeh loeation defines one row of the eharaeter. and add the start loeation of the eharaeter set: Charaeter loeation = (Code * 8) + Start of set . the eharaeter definitions are held in 4K of read-only memory (ROM) beginning at loeation 53248. if the bit is set to 0 the pixel remains in the background eolour. In normal use. If the bit is set to 1.

use the two commands: POKE 56334. PEEK(l) OR 4 POKE 56334. the definition of the letter X (character code 24 . PEEK(56334) AND 254 POKE 1.) To read the character memory. The Commodore 64 uses the memory area at 53248 for two purposes. PEEK(l) AND 251 To return to normal after reading the character memory. PEEK(56334) AND 254 POKE 1.The Commodore 64 Omnibus . PEEK(56334) OR 1 This short program will display the eight numbers defining the X. To disable input/output and switch in character ROM. This can only be done wi thin a pro gram. as the keyboard will not work once you have disabled the input/output routines. use the commands: POKE 1. to hold the character definitions and also to hold some of the input/output routines of the operating system. 10 20 30 40 POKE 56334.Part 1 128 So. PEEK(l) AND 251 FOR A = 0 TO 7 C(A) = PEEK(A+53440) .see Appendix 16) in the first character set is given by: Location = (24 * 8) + 53248 = 53440 There is one problem to be overcome before you can read the character definitions. you must first disable the input/output activities and switch in the character ROM. (This doesn't mean there are two sets of numbers in each location: there are actually two units of memory which take turns in using the same address.

Having found the eight 128 64 32 16 8 4 2 1 102 102 60 24 60 102 102 o The Character X numbers. 102. PEEK(56334) OR 1 FOR B=O TO 7 PRINT C(B) NEXT B The program should display the numbers 102. You can inspect the other characters by modifying the character number used by the program. O. PEEK(l) OR 4 POKE 56334.'s difficult to write . 102. REDEFINING CHARACTERS You may be wondering how it is possible to create new characters when the standard character definitions are held in ROM . This is to leave aspace between lines of text on the screen. we can convert them to binary form and fill in the grid to produce a letter X. 60. 102.Character Graphics 50 60 70 100 110 120 129 NEXT A POKE 1. 24. N otice that the bottom line of the character is left blank.

PEEK(56578) OR 3 POKE 56576. the other four are used to record the position in memory of the screen. there are four possible alternatives. Because of the organisation of the hardware. Only the lower 4 bits of the register form the character pointer. These numbers are definitely not in the same 16k bank. as weH: at 4096 (in the first bank) and at 40864 (in the third). As the 64 has 64K ofmemory. with the meanings shown in the table opposite. the VIC chip can find the ROM at three places. and this chip has control registers which tell it where to find the screen and the character sets. and the characters begin at 53248. and define the new characters in RAM. and tell the VIC chip where to find them. The video of the 64 is all controlled by the Video Interface Chip (or VIC). The control register of the VIC which holds the position of the character set is at memory location 53272.130 The Commodore 64 Omnibus .Part 1 new numbers into read-only memory! The answer is that we have to tell the 64 to look somewhere else for the character shapes. while the processor uses these memory . but this is a special case. The VIC chip can only look at 16K of the memory at once. so the character set and the screen must be in the same 16K bank. To make use of user defined characters you must first copy all the characters in a set into the RAM. You can then alter some (or all) of the characters to your own designs. Which of the four banks is addressed by the chip is set by the sequence: POKE 56578. The ROM holding the standard symbols is in fact very cunningly arranged to appear in two other places . We said above that in normal use the screen memory is at 1024.(PEEK(56576)AND 252) OR X where X is a number from 0 to 3.

56 POKE 53272.) Having set the bank you want the VIC to address. (PEEK(53272) AND 240) OR 14 POKE 56334. and copies the first character set into these locations: 100 110 120 130 140 150 160 REM MOVE CHARACTER SET POKE 52. The next program alters the position of character memory to 14336. and has the meaning shown in the table overleaf. PEEK(l) AND 251 FOR X = 0 TO 2047 POKE 14336+X. PEEK(56334) AND 254 POKE 1. It is best to move the character memory by using a program.32767 1 2 32768 .56: POKE 56.(PEEK(53272)AND 240) OR C C must be an even number between 0 and 14. PEEK(53248+X) .in Appendix 17.Character Graphics X BANK MEMORY RANGE 3 0 0-16383 2 1 16384 . because ifyou try moving it by typing the command at the keyboard all the displayed characters will turn into garbage. you can set the position of the character set by the command: POKE 53272.49151 0 3 49152 .65535 131 VIC Bank Selection areas for something else! (There is a diagram ofthe 64's memory .a memory map .

the formula for finding a character will be: Character Location = 14336 + (8*Character Code) .Part 1 132 START OF CHARACTER MEMORY C BANKO BANK 1 BANK2 BANK 3 0 0 16384 32768 49152 2 2048 18432 34816 51200 4 4096 20480 36864 53248 6 6144 22528 38912 55296 8 8192 24576 40960 57344 10 10240 26624 43008 59392 12 12288 28672 45056 61440 14 14336 30720 47104 63488 Character Memory Positions 170 180 190 NEXT X POKE 1. With the character set in the new position.The Commodore 64 Omnibus . You will now be able to modify the characters by POKEing new values into the memory. If you run this program. These reduce the amount of the memory used by the BASIC program so that it does not store data over the new character set. you should see any characters on the screen turn to garbage when the memory pointers are swi tched and then return to normal as the character data is copied into the new area. PEEK(56334) OR 1 There is an extra pair of POKE commands in line 110 of the program which we have not dealt with before. PEEK(l) OR 4 POKE 56334.

) The screen position within a bank is controlled by the four most significant bytes of the VIC control register at location 53272. while 24K lies unused. . all the characters will be turned upside down . To move the screen to another location. MOVING THE SCREEN Moving the character memory to the first 16K bank has the advantage that you don't have to move the screen memory. use the command: POKE 53272. (Refer to the memory map in Appendix 17. but itmeans that you can not use more than 12K of the memory for BASIC pro grams. To make better use of the memory you must move both the character memory and the screen to a higher bank. (PEEK(53272)AND 15) OR S S indicates the location within the bank of the beginning of screen memory and has the meaning given in the table overleaf.Character Graphics 133 If you add these lines to the pro gram and then RUN 1000. C(Z) NEXT Z NEXT X RUNning the first program again will restore the original characters at the new have redefined them! 200 1000 1010 1020 1030 1040 1050 1060 1070 1080 END REM INVERT CHARACTERS FOR X = 14336 TO 16376 STEP 8 FOR Y = 0 TO 7 C(Y)=PEEK(X+Y) NEXT Y FOR Z=O TO 7 POKE X+7-Z.

as weIl as telling the VIC chip where it is. Location 648 records the address of the beginning of the screen. thus: POKE 648. you must tell the 64's operating system where it has gone. so that the PRINT command will write to the correct area.Part 1 134 START OF SCREEN MEMORY S BANKO BANK 1 BANK2 BANK3 0 0 16384 32768 49152 16 1024 17408 33792 50176 32 2048 18432 34816 51200 48 3072 19456 35840 52224 64 4096 20480 36864 53248 80 5120 21504 37888 54272 96 6144 22528 38912 55296 112 7168 23552 39936 56320 128 8192 24576 40960 57344 144 9216 25600 41984 58368 160 10240 26624 43008 59392 176 11264 27648 44032 60416 192 12288 28672 45056 61440 208 13312 29696 46080 62464 224 14336 30720 47104 63488 240 15360 31744 48128 64512 Screen Memory Positions When you move the screen. (Screen Start)/256 . and must be POKEd with the address ofthe screen divided by 256.The Commodore 64 Omnibus .

which is then used to program the character. C IF C < 0 OR C > 255 THEN 210 SX = 28672+C*8 SC = 27648:CC= SC+331 REM STORE CHARACTER DATA IN ARRAY PRINT "{CLS}" FOR R=l TO 8:GOSUB 1000:NEXT R REM DISPLAY CHARACTER GOSUB 2000 IF F=l THEN END X=l: R=l B = PEEK(CC) REM MODIFY CHARACTER GOSUB 3000: IF EX = 1 THEN RETURN IF CL=l THEN CL=O: GOTO 400 300 310 395 400 410 420 500 510 520 530 *********************** * * * CHARACTER GENERATOR * * * *********************** .Character Graphics 135 CHARACTER GENERATOR PROGRAM This program allows you to design new characters on the screen and add them to the character set.108: CLR GOSUB 20000: REM SETTING UP ROUTINES GOTO 10000: REM MAIN MENU 190 192 194 REM *********************** REM * REDEFINE CHARACTERS * REM *********************** 200 210 220 230 240 295 EX=O: PRINT "{CLS}" INPUT "CHARACTER CODE". 10 11 12 13 14 REM REM REM REM REM 100 110 120 POKE 52.108: POKE 56. The characters are created by filling in a large grid on the screen.

1: NEXT: NEXT FOR R=l TO 8 FOR X=l TO 8 IF A%(R. FOR 1=55627 TO 55907 STEP 40 FOR 11=0 TO 7: POKE 1+11. R+6: PRINT: PRINT TAB(24) STR$(A%(R. I) = 0 NEXT I RETURN 1990 1992 1994 REM ********************* REM * DISPLAY CHARACTER * REM ********************* 2000 2003 2005 PRINT "{CLS}".X) = 1 N = INT(N/2): X=X-l IF N >=1 THEN 1040 FOR I=X TO 1 STEP -1 A% (R.9» NEXT R 2010 2020 2030 2035 2040 2050 2060 2070 ************************ * STORE CHARACTER DATA * * IN ARRAY * ************************ .X)=O: GOTO 1050 A%(R.X)=l THEN CS = 160: GOTO 2040 CS=46 POKE SC+(X+I0+(R+7)*40).The Commodore 64 Omnibus .9) = N: REM VALUE OF ROW REM STORE BIT PATTERN IF N/2 = INT(N/2) THEN A%(R. CS NEXT X POKE 214.Part 1 136 540 550 CC = SC+X+40*(R+7)+10 GOTO 500 990 992 994 996 REM REM REM REM 1000 1010 1020 1030 1040 1045 1050 1060 1070 1080 1090 1100 N = PEEK( SX+R-l ) X=8 A%(R.

B : X=X+1: RETURN: REM RIGHT IF K$="{ CD}" AND R<8 THEN POKE CC.1: RETURN: REM UP = 1IF K$=" 11 THEN A%{R.1: RETURN: REM LEFT IF K$="{ CR}" AND X<8 THEN POKE CC.Character Graphics 137 2080 RETURN 2990 2992 2994 2996 REM ***** ***** ***** **** REM * MOVE CURSOR AND * REM * CHANGE PIXEL S * REM ***** ***** ***** **** 3000 3010 3020 3030 REM CHECK KEYBOARD GET K$ REM FLASH CURSOR CH = PEEK {CC): C%={CH OR 128) (CH AND 128) POKE CC. C%:FOR 11=1 TO 100:N EXT 3040 3050 3060 3080 3090 3100 3110 3120 3130 3140 3150 3160 3190 3192 3194 CHECK KEY INPUT REM IF K$=" " THEN 3010 IF K$=" {CL} " AND X>l THEN POKE CC.B : R=R+ 1: RETURN: REM DOWN IF K$="{ CU}" AND R>l THEN POKE CC.B : R=R.X) CHANGE REM A%{R . B: X=X.B: RETURN RETURN REM **************** REM * CHANGE PIXEL * REM **************** .X): GOTO 3200 : PIXEL IF K$=" P" THEN 4000: REM REPROGRAM CHARACTER IF K$=" {CLS }" THEN 3300: REM CLEAR CHARACTER IF K$="{HOM}" THEN X=l: R=l: POKECC.

160: RETURN 3290 3292 3294 REM **** **** **** **** **** REM * CLEAR CHARACTER * REM **** **** **** **** **** 3300 3310 3320 3330 FOR R=1 TO 8: FOR X=1 TO 9 A%(R .X)=O NEXT:NEXT CL=I: RETU RN 3990 3992 3994 REM **** **** **** **** **** *** REM * REPROGRAM CHARACTER * REM **** **** **** **** **** *** 4000 4020 4030 4040 4050 4060 4070 4080 4100 M$ = "REPROGRAMMING CHARACTER" + STR$ (C) POKE 214.Part 1 3200 3210 IF B=16 0 THEN POKE CC.138 The Comm odore 64 Omnib us .X) NEXT X POKE SX+R -l. 46: RETURN POKE CC.2 1: PRIN T: PRINT TAB( 5) M$ FOR R=1 TO 8 FOR X=1 TO 8 o = 0+(2 t(8-X » * A%(R . 0 0=0: NEXT R EX=1 RETURN 9990 9992 9994 REM ************* REM * MAIN MENU * REM **** **** **** * 4010 10000 PRINT "{CLS }{CO }{CO }" TAB( 12) "CHARACTER GENERATOR" 10010 PRIN T: PRIN T: PRINT "{RVS}C{ROF}HANGE CHARACTERS" 10020 PRIN T: PRIN T: PRINT "{RVS}L{ROF}OAO CHARACTER SET FROM TAPE" .

"CHARACTERS" 11010 FOR C=O TO 2047 11020 GET#l.1. C$: IF C$="" THEN C$=CHR$(O) 11030 POKE 28672+C. ASC(C$) 11040 NEXT C 11100 CLOSE 1 11500 RETURN 11990 REM ********************** 11992 REM * SAVE CHARACTER SET * 11994 REM ********************** 12000 PRINT "{CLS}{CD}{CD}": OPEN 1.Character Graphics 139 10030 PRINT: PRINT: PRINT "{RVS}S{ROF}AVE CHARACTER SET TO TAPE" 10040 PRINT: PRINT: PRINT "{RVS}F1{ROF} END PROGRAM" 10090 REM READ KEYBOARD 10100 GET K$: IF K$="" THEN 10110 10110 IF K$="C" THEN GOSUB 200: GOTO 10000: REM CHANGE CHARACTERS 10120 IF K$="L" THEN GOSUB 11000: GOTO 10000: REM LOAD CHARACTER SET 10130 IF K$="S" THEN GOSUB 12000: GOTO 10000: REM SAVE CHARACTER SET 10140 IF K$="{F1}" THEN END 10150 GOTO 10100 10990 10992 10994 10996 REM ********************** REM * LOAD CHARACTER SET * REM * FROM TAPE * REM ********************** 11000 PRINT "{CLS}{CD}{CD}": OPEN 1.1.0. "CHARACTERS" 12010 FOR C=O TO 2047 .1.

(PEEK(53272) AND 240) OR 12 20040 POKE 53272.Part 1 140 12020 12030 12040 12100 12500 C$ = CHR$(PEEK(28672+C». PEEK(56334)AND 254 20090 POKE 1. PEEK(l) AND 251 20100 FOR 1=0 TO 2047 20110 POKE 28672+1.9) 20010 POKE 56578. I: POKE 55696+1. and move the screen .The Commodore 64 Omnibus . and to save character sets on tape and reLOAD them. 108 20060 PRINT "{CLS}{CD}{CD}{CR}{CR}COPY1NG CHARACTER SET" 20070 FOR 1=0 TO 255: POKE 28048+1. (PEEK(56578) AND 252) OR 3 20020 POKE 56576. PEEK(56334) OR 1 20500 RETURN The pro gram allows you to redefine any character. PRlNT#l. C$ NEXT C CLOSE 1 RETURN 19990 REM *********************** 19995 REM * SETTING UP ROUTlNES * 20000 REM *********************** 20005 DlM A%(8. other pro grams. PEEK(l) OR 4 20160 POKE 56334. You can use the new character sets wi th . The first thing the progam does is copy the character set in to RAM. 3: NEXT 20080 POKE 56334. PEEK(53248+1) 20120 NEXT I 20150 POKE 1. (PEEK(53272) AND 15) OR 176 20050 POKE 648. (PEEK(56576) AND 252) OR 2 20030 POKE 53272.

SAVEing a character set onto tape is performed by the subroutine at 12000. giving you the option to change a character or to LOAD or SA VE a character set. Lines 10000 to 10150 then display the menu. The HOME key returns the cursor to the top left corner of the grid. as these take less tape than integer or real variables. The character sets are reloaded into the machine by the routine at 11000. pressing P will store the new definition in character memory. Pressing the function key F1 stops the program. use the CLR key. To use the new characters you create with other programs. so the test in line 11020 is included to correct this. Lines 4000 to 4100 perform this function. The modification of the character is performed by the section ofprogram at 3000. then stop the pro gram and type NEW. To erase all the data for a character. You may move the cursor around the character grid wi th the cursor keys. the 64 reads a CHR$(O) as a null character. Lines 20005 to 20500 do this. When loading from tape. displaying the character set as i t is copied. The bytes of data are stored on the tape as single character string variables. The new character set . the line 310 calls the routine at lines 1000 to 1100 to store the data of the character in an array. use this pro gram to create the characters. The character is then displayed on the screen by the routine at 2000. When you have finished designing the new character. When you input the code ofthe character you wish to alter.Character Graphics 141 memory to give a large amount ofmemory still free for use by BASIC. The redefining of characters is controlled by the routine from 200 to 550. or to LOAD them from tape.

however.15. Multi colour character mode is enabled by setting bit 4 of the VIC control register at location 53270. the character is displayed in multi colour mode. PEEK(53270) OR 16 and disabled by: POKE 53270. The horizontal resolution (but not the width) of the characters is reduced to halfthat of anormal character . four colours may be used for each character. If the foreground colour is 8 . The new characters will be lost. and you can LOAD and RUN other programs. as folIows: POKE 53270. the character appears as normal. which represent a grid of eight rows. instead of the two allowed in normal character mode. PEEK(53270) AND 239 Once multi colour character mode is enabled for the whole display.142 The Commodore 64 Omnibus . WARNING Do not reset the 64 by using RUN/STOP and RE STORE.Part 1 will remain. A multi colour character is defined in a similar way to anormal character by eight bytes of the character memory. each character may be set to multi colour character mode or to standard mode. If the foreground colour of the character is between 0 and 7. but the screen will not be properly reset.a multi colour character has four columns of definable pixels which are twice as wide as normal. . and you will not be able to see what you are typing. In multi colour character mode. MULTI COLOUR CHARACTERS In multi colour character mode.

and 10 gives the colour in Background 2 at 53283. which is defined by Iocation 53281. 10. and 11 . If the bit pair of a pixel is set to 00. .00. The combination 01 specifies the colour stored in the Background 1 register at 53282. Ifthe bit pair is set to 11. is Extended Background Colour Mode. referred to as Background 0.143 Character Graphics o 1 2 3 Memory Location: 4 5 6 7 Bit: 7 654 3 2 o The Multi Colour Character Grid each pixel in the character corresponds to two bits ofthe memory location defining the row. 01. A final variant of character graphics. the colour used is the screen background colour. There are four possible combinations of two bits . less complex than multi colour character mode and very much easier to use.and each combination specifies a different colour. The colour memory extends from 55296 to 56295. the pixel is set to the colour specified by the lower three bits of the colour memory for the character (the fourth bit sets multi colour character mode on or off for the character).

instead of just one.255 11 53284 53283 . Try this short routine to see the effect of extended background colour mode: 5 POKE 53265. by the command: POKE 53265. PEEK(53265) OR 64 . CHARACTER COLOUR COLOUR REGISTER CODE 0-63 64 -127 53281 53282 128-191 00 01 10 192 .144 The Commodore 64 Omnibus . The colours are stored in locations 53281 to 53284. you are restricted to using the first 64 characters of the character set.Part 1 EXTENDED BACKGROUND C-OLOUR MODE Extended background colour mode allows you to use four different background colours for the characters. PEEK(53265) AND 191 When extended background colour mode is set. PEEK(53265) OR 64 and is disabled by: POKE 53265. Extended background colour mode is enabled by setting bit 6 of the VIC control register at 53265. as the two highest bits of the character code in screen memory are used to control the background colour of the character.

Character Graphics 10 20 30 50 60 70 80 145 FOR C=54296 TO 54299 POKE C. 193 Lines 10 to 30 of the routine set the foreground colour of the first four characters of the display. 1 POKE 1025. If you hold down the CTRL key and press RVS ON. 129 POKE 1027. 14 NEXT C POKE 1024. you will find that the third and fourth background colours become available when typing wi thou tor wi th the SHIFT key. The first four screen locations are then set to the character code for A wi th each of the four background colours. . which makes it very easy to use. This makes extended background colour mode a useful feature for producing colourful displays with very little effort. When you RUN the program you should see four letter As. and typing with the SHIFT key engaged gives the second colour. 65 POKE 1026. Normal typing will give you the first background colour. is that you can produce all four background colours wi thou t having to POKE numbers onto the screen. each with a different background colour. One advantage of extended background colour mode.

The data describing the characters which can be displayed is held in an area of memory known as character aresolution of 160 * 200 pixels in four aresolution of 320 pixels in two colours * 200 MULTI COLOUR . where each character description takes up a block of eight bytes. As described in Chapter 12. each of these pixels is individually addressable.a feature not documented in the Users Guide. There are two types ofBit Mapped mode: STANDARD . Each pixel comprising that character is defined by a single bit in one ofthese eight bytes. In Bit Mapped mode. . but which is one of the most powerful features of the machine. allowing you to create high resolution pictures. The use of bit mapped mode is very similar to User Defined character mode in that you can consider the screen to comprise 1000 tblank' characters a wai ting definition. with 25 rows of 40 characters.CHAPTER 13 HIGH RESOLUTION GRAPHICS This chapter deals with the creation of high resolution displays using Bit Mapped mode . occupies one thousand bytes ofmemory. the standard Commodore 64 screen display.

before the memory is cleared by line . with a statement like: FOR Z = 8192 TO 16191:POKE Z.O: NEXT Let's eonvert these statements into a program: 10 20 30 POKE 53272. CLEARING THE DISPLAY Before we ean ereate a bit mapped mode display.O: NEXT Notiee how the sereen fills with random patterns and eolours.PEEK(53265) OR 32 FOR Z=8192 TO 16192: POKE Z. We ean alloeate this by changing the VIC TI memory pointer register at loeation 53272.PEEK(53272) OR 8 POKE 53265. A eonvenient plaee to start the bit mapped display is loeation 8192. we must set bit 5 in this loeation.High Resolution Graphics 147 STANDARD BIT MAPPED MODE The display mode is governed by the VIC eontrol register at loeation 53265. (see Appendix 17) and to do this we ean use an instruetion like this: POKE 53272. we must first clear the memory area set aside for the display.PEEK(53272) OR 8 This leaves about 8k free for programs. To select Standard bit mapped mode. using a statement like this: POKE 53265. PEEK(53265) OR 32 Sinee there are 1000 possible eharaeter loeations with 8 bytes needed to define the data for eaeh. we will need a memory area of 8000 bytes for our bit mapped mode display.

This is because characters in the standard screen memory (from 1024 to 2048) are now being interpreted as colour data for the bit mapped mode screen. we see that the code for white is 1. The number describing this colour combination is calculated like this : . with the restriction that only one combination of colours is possible in each 8 by 8 section of the screen. me ans that since we want a blue background bits 1 and 2 must be set. To remove these the program must clear this area of memory to a single colour. COLOUR IN BIT MAPPED MODE The colour of bit mapped mode displays is controlled by data in the 1000 standard screen memory locations in the following way: 7 I 6 I 5 I4 FOREGROUND COLOUR 3 121 1 I 0 BACKGROUND COLOUR For every byte in standard screen memory.Part 1 148 30. For a white foreground. bit 4 must be set.The Commodore 64 Omnibus . From the table in Appendix 5. we will calculate the appropriate code for colour memory to set the display to a blue background with white pixels. Since four bits can describe sixteen possibilities.these correspond to any data left on the standard display when you typed RUN (the program listing for example). bits 0 to 3 determine the background colour and bits 4 to 7 determine the foreground colour in that 8 by 8 pixel area of the display. As the memory is cleared. bit mapped mode displays can be in any of the CBM -64's sixteen possible colours. As an example. you may see blocks of colour remaining . and the code for blue is 6. which .

................. o .............. ..... ............................ I I-+-t-+-+++++-++-+_ .................. X I-+-t-+-+++++-++-+_ ......... o I-I-+-+-+++++-+-Hr--" ........... S V E R T I C A L L ~~~~--~~--------~ Y ...................... E I-+-r-+-+-++++-+-+-I--" ........... .... .... BIT MAPPED MODE DISPLAY MEMORY The Bit Mapped mode display is set out like this: 320 PIXELS HORIZONTALLY H-t-+-+-+-+-+-++++-_...22:NEXT HIGH RESOLUTION DISPLAYS Now that we have selected bit mapped mode................. ................ 2 I-I-+-+-+++++-+-Hf--... .................. ............... ... ................................................. P H-t-+-+-+-+++-t-H-.............. to create a high resolution display we need to know how to select individual bits from the 8000 bytes of display memory............. add the line: 40 FOR Z=1024 TO 2023:POKE Z........................ and set those bits corresponding to the pixels we want to display................................................ I-+-r-+-+-++++-+-+-I-' ...................... I-I-+-+-+++++-+-Hr--' .................................... I-+-+-+-+++++-++-+r-' ..High Resolution Graphics 2f 1 +2f2+2f4= 149 22 To select this colour combination......................................... To do this we will first examine how the 8000 byte display memory is arranged.. ................. L H-t-+-+++++-t-H..................................

327 335 343 351 359 367 375 312 313 314 315 316 317 318 319 632 633 634 635 636 637 638 639 where the numbers represent bytes ofmemory.fortunately something your CBM -64 can do for you! If we describe the position of a pixel in terms of i ts X and Y coordinates. 326 . .The Commodore 64 Omnibus .Part 1 150 The arrangement of the first 16 rows of display memory for the Bit Mapped mode display looks like this: 0 1 2 3 4 5 6 7 8 9 10 16 17 18 24 25 26 320 328 336 344 321 329 322 323 324 325 . so that to be able to address any bit in this memory requires some calculation . we can calculate for the appropriate byte: a) Its row in the display memory: ROW = INT(Y/8) . . Notice that the memory isn't set out in an immediately obvious way. . and a vertical group of eight such bytes represents one character position of the standard 25 line character mode display.

PEEK(BYTE)OR 2jBIT To see this subroutine in action. any pixel given its X and Y coordinates. 999 1000 1010 1020 1030 1040 1050 REM DISPLAY PIXEL ROW = INT (Y/8) COL = INT (X/8) LINE = Y AND 7 BIT = 7 .High Resolution Graphics 151 b) Its column position within that row: COL = INT (XIS) c) Its line position within that row: LINE = Y AND7 We can also define the appropriate bit within that byte: BIT = 7 -(X AND 7) We can combine all these calculations in a short subroutine which will calculate the position of.O:NEXT FOR I = 1024 TO 2023:POKE I.22:NEXT FOR J = 0 TO 200 X = INT(RND(1)*320) Y = INT(RND(1)*200) . here is a short pro gram using what we have learned so far to simulate a cloudless summer's night! The Sky at Night 10 20 30 40 50 60 70 POKE 53272. and display.PEEK(53272) OR 8 POKE 53265.(X AND 7) BYTE = 8192 + ROW*320 + COL*8 + LINE POKE BYTE.PEEK(53265) OR 32 FOR I = 8192 TO 16192:POKE I.

we can draw dotted lines .(X AND 7) BYTE = 8192 + ROW*320 + COL*8 + LINE POKE BYTE.The Commodore 64 Omnibus . by changing lines 50 to 80 and deleting line 90 in the last program we can draw a horizontalline across the middle ofthe screen: 50 60 70 80 Y = 100 FOR X =0 TO 319 GOSUB 1000 NEXT X Similarly.PEEK(BYTE)OR 2tBIT RETURN 1050 1060 In a more practical vein. For example.try changing line 60 in the last pro gram to: 60 FOR Y = 0 TO 219 STEP 3 A further modification will allow you to draw circles and ellipses: 50 R = 50 . we can use the pixel plotting subroutine to draw lines in bit mapped mode. we can draw a verticalline: 50 60 70 80 X = 100 FOR Y = 0 TO 199 GOSUB 1000 NEXT Y By adding a STEP to line 60.Part 1 152 80 90 100 999 GOSUB 1000 NEXT J GOTO 100 REM DISPLAY PIXEL 1000 1010 1020 1030 1040 ROW = INT (Y/8) COL = INT (X/8) LINE = Y AND 7 BIT = 7 .

01 X=R * SIN(I)+160 Y=R * COS(I)+100 GOSUB 1000 NEXT GOTO 110 This pro gram will draw a circle of radius R (set in line 50) with its centre at the middle ofthe screen. we are not restricted to one foreground and one background colour over the entire screen.PEEK(53272) OR 8 .1 X = 160 + R*SIN(J/32*n) Y = 100 + R*COS(J/32*n) GOSUB 1000 NEXT J GOTO 120 You will notice that these programs do not run very quickly.75 * R * SIN(I)+160 The following modifications will cause the computer to draw a spiral in the centre of the screen: 50 60 70 80 90 100 110 120 R = 50 FOR J = 0 TO 500 R = R . because the CBM-64 is not equipped with BASIC commands to control its high resolution displays.High Resolution Graphics 60 70 80 90 100 110 153 FOR I = 0 TO 2*n STEP . here is a program which will draw different coloured lines across the screen: 10 POKE 53272.0. To speed up the process would require the use of machine code. only in each 8 by 8 pixel block. To demonstrate this. As mentioned above. To convert the program to draw an ellipse simply add a reducing factor to either line 70 or line 80: 70 X = 0.

every screen line) by adding 16 to the variable X.O:NEXT I FOR I = 1024 TO 2023 POKE I.Y GOTO 150 Lines 40 to 80 set the foreground colour to light green in the normal way but the background colour is changed every 40 bytes (Le. thereby increasing the value of the foreground colour code by one. This is because instead of calculating the position of every bit and setting it to 1. each line is drawn in a different colour. each byte is set to 255 (thus setting each bit to 1) since we are only drawing straight lines. This trick makes the drawing ofhorizontallines in high resolution mode tolerably fast. the cursor keys move . Consequently.255 NEXT X.Part 1 154 20 30 35 40 50 60 70 80 100 110 120 130 140 150 POKE 53265.The Commodore 64 Omnibus . Here is a short program which allows you to draw on the standard bit mapped mode screen.PEEK(53265) OR 32 FOR I = 8192 TO 16191 POKE I. Another point to notice about this program is that the lines are drawn much more quickly than in previous examples. but of course is no use in drawing any other type ofline. Adding 16 has the effect ofincrementing the most significant 4 bits of that byte.13+X IF I/40=INT(I/40) THEN X = X+16 IF X=256 THEN X=O NEXT I FOR Y=4 TO 124 STEP 8 FOR X=O TO 39 BYTE = 8192+INT(Y/8)*320+X*8 POKE BYTE. The F1 function key toggles between dra wand erase modes (indicated by the border colour changing from green to red).

the pro gram is slow to use and further reinforces the point that without machine code.High Resolution Graphics 155 the cursor around the screen. 2-(MO=1)*3): GOTO 505 GOTO 500 REM REM ************** REM * * REM * PLOT PIXEL * REM * * REM ************** REM . Because of the speed limitations mentioned above.22: NEXT REM REM ***************** REM * * REM * GET KEY PRESS * REM * * REM ***************** REM CC = PEEK(BY) GET K$: IF K$="" THEN POKE BY. PEEK(53272) OR 8 POKE 53265. PEEK(53265) OR 32 FOR I = 8192 TO 16191 POKE I.O:NEXT I FOR I = 1024 TO 2023 POKE I. PEEK (BY) AND 255-2tBI:GOTO 505 IF K$="{CU}" AND Y>O THEN Y=Yl:GOSUB 1000 IF K$="{CD}" AND Y<199 THEN Y=Y~l: GOSUB 1000 IF K$="{CR}" AND X<319 THEN X=X+1: GOSUB 1000 IF K$="{CL}" AND X>O THEN X=X1: GOSUB 1000 IF K$="{F1}" THEN MO=l-MO: POKE 53280. PEEK(BY) OR 2tBI: POKE BY. high resolution graphics aren't very fast on the 64! 100 110 120 130 140 150 493 494 495 496 497 498 499 500 505 510 520 530 540 550 560 993 994 995 996 997 998 999 POKE 53272.

Part 1 156 POKE BY. The drawback is that horizontal resolution is halved. and adjacent pixels may be different colours. The 64 offers a way round this with multi colour bit mapped mode.PEEK (BY) OR 2 t BI 1060 IF MO=l THEN POKE BY. with the display width being reduced to 160 pixels . so the width of the whole display does not change.PEEK (BY) AND 255-2 t BI 1070 RETURN 1000 1010 1020 1030 1040 1050 Whilst standard bit mapped mode allows very high resolution graphics. . CC: CH = INT(X/8) RO = INT(Y/8) LN = Y AND 7 BY = 8192 + RO*320 + 8*CH + LN BI = 7-(X AND 7) IF MO=O THEN POKE BY. Colours in multi colour bit mapped mode are selected from ei ther: a) Background register 0 (53281).each pixel occupies twice the normal width. Here again there is a parallel wi th multi colour characters in that up to four colours are allowed in each 8 by 8 block.The Commodore 64 Omnibus .each pixel in every 8 by 8 block must be in the same colour. however. it doesn't allow much flexibility in terms of colour . MULTI COLOUR BIT MAPPED GRAPHICS To allow the display of up to four foreground colours the VIC TI chip treats the data in the 8000 byte display memory in a slightly different way.

half a byte). c) The least significant nybble of screen memory. .High Resolution Graphics 157 b) The most significant nybble of sc~een memory (a nybble is four bits . d) Creating a display in multi colour bit mapped mode requires a lot of planning. The final step would be to calculate data from the groups of 4 bit pairs. and use a pro gram to POKE this data into the appropriate byte of bit mapped mode screen memory to recreate your picture. The least significant nybble of colour memory. It is best to draw your design on graph paper first. as we shall see in the next chapter. BIT PATTERN SOURCE OF COLOUR DATA 00 BACKROUND REGISTER 0 01 HIGH NYBBLE OF SCREEN MEMORY 10 LOW NYBBLE OF SCREEN MEMORY 11 LOW NYBBLE OF COLOUR MEMORY The technique is much the same as for multi colour characters. and calculate the bit patterns for the appropriate pixels according to this table. decide on which areas will be the same colour. since each of the 1000 screen character locations can contain up to 4 independent colours. and for multi colour sprites.

are a special breed of user defined characters . but are endowed with a few extra facilities which make them a flexible and simple way of creating moving high resolution displays. One of the reasons sprites are so useful is that you can move them around the screen very easily. The Sprite Grid . The CBM-64 allows you to use up to 8 sprites at a time. This makes moving graphics in BASIC very easy to create. simply by giving them an X and Y coordinate based on the 320 by 200 pixel bit mapped display and the VIC TI chip does all the rest. each ofwhich can be in anyone of16 colours. or Moveable Object Blocks as they are sometimes known.CHAPTER 14 SPRITES Sprites.that is they operate on similar principles.

. The sprite is designed by filling in the squares on the grid which correspond to the pixels ofthe sprite we want to be illuminated. like the one shown on the previous page. the shape of asprite is defined by a block of memory locations. To convert the familiar character above into data describing the sprite we use exactly the same technique as for user defined characters. sprites are rather larger than user defined characters comprising 24 horizontal pixels by 21 vertical.Sprites 159 Like a user defined character. each bit of which determines the state (on or om of a pixel. Let's start by creating asprite and see what we can do with it. However.

This means we will need 63 bytes to store the data describing our sprite. The bytes are arranged to read from left to right. we have 24 * 21 = 504 pixels. which is exactly the same as that given for user-defined characters.Part 1 The difference is that instead of having 64 pixels described in eight bytes.160 The Commodore 64 Omnibus . so byte 0 contains the data for the top left hand 8 pixels. byte 1 the next 8 on that row. and so on: BYTE 0 BYTE 1 BYTE 2 BYTE 3 BYTE 4 BYTE 5 BYTE 60 BYTE 61 BYTE 62 Rather than go through the process of converting the picture into DATA statements. here is the data for our sprite: o o 1 3 7 15 31 31 63 63 63 63 63 254 255 255 255 255 o 126 255 247 227 247 255 255 254 252 248 248 252 o o 128 192 224 o o 128 192 224 192 128 o o o o o o 31 31 15 7 3 .

This area of memory is the eight bytes immediately after the screen memory. One convenient place is the cassette input buffer. in normal circumstances this means locations 2040 to 2047. The cassette buffer is located between address 828 and 1019 giving us 191 bytes of<safe' memory. we must bear in mind that the VIC II chip can only access one bank of 16k bytes at a time. Each of these locations contains a <pointer' to the start of a 64 byte block of memory con taining spri te data. which is an area ofmemory set aside for temporary storage of data on its way to and from the cassette unit. STORING SPRITE DATA When allocating space for sprite data. In fact there is a little more since the eight bytes before the tape buffer and the four after it are unused . To indicate to the VIC II chip the whereabouts of the sprite data. we need to store the data somewhere and tell the VIC II chip where to find it.203 bytes in all.Sprites 255 255 126 192 128 o 161 1 o o Having defined the sprite in terms of 63 bytes of data. All that now remains is for us to POKE the data into the appropriate locations. To indicate a block of memory in the cassette buffer. and that the data must be kept in an area which is protected from BASIC. set the pointer for Sprite 0 to . starting at location 832 the pointer would contain the value 832 (13*64). The pointer for Sprite 0 is at 2040. 8 bytes of memory have been set aside to serve as pointers to the beginning of the data. for Sprite 1 at 2041 and so on.

The Commodore 64 Omnibus .63 DATA 248.128. let's put what we have learned so far into program form: 10 20 30 40 50 60 70 80 999 1000 1010 1020 1030 1040 1050 1060 1070 REM CREATE SPRITE FOR Z=OT063:REM READ SPRITE DATA READ D POKE 832+Z.3.192.252 DATA 1 162 point to it.PEEK(53269) AND 255-2tN Before we discuss sprites in greater detail.0 DATA 31. and tell the VIC TI chip to display the sprite.255.0.63 DATA 254.63. So.7.31. BUFFER NEXT Z POKE 2040.13: REM POINT TO DATA POKE 53269. The VIC TI chip provides control over which sprites are visible by means of the SPRITE EN ABLE REGISTER at location 53269.192 . Each bit in this register controls one sprite .31 DATA 255. a given sprite may be made visible with a BASIC statement: POKE 53269. the sprite is visible.0.255 DATA 128. a 0 means it is invisible. REM SPRITE 0 ON END REM DATA FOR SPRITE 0 DATA like this: POKE 53269.D:REM CASS.if it is set to OR 2tN where N is the sprite number (0 to 7).1.254.227 DATA 224. Turning a sprite off involves setting the appropriate bit to 0.248.0.

192 1090 DATA 1.ifit is set. you will notiee that not all ofthe sprite is visible. and 110 pixels from the top.255.3. Ifyou use very small or very large numbers for the Y position register (53249).110 .128.. This is because there are only 220 possil?le loeations in the vertieal direction on the sereen. you will not be able to see the sprite.the sprite becomes visible! The two locations we POKEd were the SPRITE POSITION REGISTERS for Sprite O. and the Y position register can eontain numbers between 0 and 255. The position registers ean only hold numbers up to 255.0. and the sereen is 320 pixels wide.0 If you RUN the program. known as the X MSB REGISTER.0. This problem is solved by the use of a further register at loeation 53264. Y ou may also eome aeross another problem . Eaeh bit in this register eorresponds to one sprite .126. This means that a value of less than 30 in the Y position register will display the sprite above the top of the to get the sprite over to the extreme right hand edge of the sereen.224. The numbers we used told the VIC II ehip to display the sprite at a position 160 pixels from the left ofthe display. To do this.255. that sprites X Position Register value is added to 255 to ealeulate .Sprites 163 1080 DATA 7. and a value greater than 249 will put it out ofsight beyond the bottom. This is because we have not indicated to the VIC II chip where we want the sprite to be displayed.160:POKE 53249. Try PO KEing the position registers wi th other numbers and notice how the sprite moves almost instan taneously. type in the following commands in immediate mode: POKE 53248.255.

Notice that all sprites are the same design because every sprite data pointer is set to point at the same data by lines 70 and 80. Try POKEing this location with a few values (0-15) and watch the colours change. For Sprite 0. Try this in immediate mode by setting the X position register to 30: POKE 53248.255 FOR N=O TO 15 STEP 2 .30 and setting the X msb register for Sprite 0: POKE 53264. A FLOCK OF SPRITES 10 20 30 40 50 60 70 80 90 100 PRINT /I{CLS}/I R = 53248: X = 100:Y = 100 FOR I=O TO 63 READ D POKE 832+I.D NEXT I FOR I=2040 TO 2047 POKE I. the SPRITE COLOUR REGISTER is at location 53287. The following pro gram will display all 8 sprites in different colours and move them around the screen.Part 1 164 its position on the screen. SPRITE COLOURS. Notice that the screen background shows through those parts of the sprite where no pixels are defined.1 -the spritejumps from one side ofthe screen to the other. Each sprite can be displayed in any of 16 possible colours and the colour is controlled by yet another register.13:NEXT I POKE 53269.The Commodore 64 Omnibus . if i t is 0 then the sprite has a higher priority than the background data and will pass in front of it. the lowest numbered sprite appearing to cross IN FRONT of the other. DATA 247.255.255 DATA 128. then it will cross 'behind' any background data.31 DATA DATA 63. by using the SPRITE TO BACKGROUND REGISTER at 53275.192.1.Sprites 110 120 130 140 150 160 170 180 1000 1010 1020 1030 1040 1050 1060 1070 1080 165 X=X+(RND(1)*20)-(RND(1)*20) Y=Y+(RND(1)*20)-(RND(1)*20) IF X>255 OR X<O THEN X=100 IF Y>249 OR Y<30 THEN Y=100 POKE 53248+N.0. If the bit associated with a sprite in this register is a 1. This sprite to sprite display priority is pre-determined. SPRITE PRIORITIES You will notice that when two sprites collide they cross over each other.1.0.63. the lowest numbered sprite will always cross on top of the other.31 DATA It is possible to control the sprite to background priority.63. The following program demonstrates this: 5 10 20 PRINT"{CLS}" FOR I=O TO 63 READ D . so that sprites can be made to appear to cross in front of or behind other screen data.X POKE 53249+N.Y NEXT N GOTO 100 DATA 0.254.252 DATA DATA 3.0.255 DATA 224.

140 53264. 53269.0:POKE 53288.140 53250.3 53251.D:NEXTI 2040.255.96 240.1-PEEK(53275) NEXT C 1000 1010 1020 1030 1040 1050 DATA DATA DATA DATA DATA DATA 110 120 200 210 220 230 240 250 260 270 280 290 832+I.12.56.0 . 1 IF X1=0 THEN X1=255: POKE 53264.192.24.The Commodore 64 Omnibus . 1 166 30 40 50 60 70 75 80 POKE POKE POKE POKE POKE POKE POKE 100 300 W$=" {RED}{RVS} {ROF} {PUR}{RVS} {ROF} {GRN} {ROF} {RVS} {YEL} {ROF} {RVS}" PRINT"{HOM}{CD}{CD}{CD}{CD}" FOR I=O TO 11:PRINT W$:NEXT FOR C=l TO 345 XO=PEEK(53248) X1=PEEK(53250) IF XO=255 THEN XO=O: POKE 53264. 24. 28.0.1 53248.24.6.X1 IF XO/80=INT(XO/80) THEN POKE 53275.24.255.XO POKE 53250. 53249.7.255. 24 1070 DATA 56.3 24.13:POKE 2041.255. 0 XO=XO+1 X1=X1-1 POKE 53248.112. 255 1060'DATA 53287.

use the following statement: X direction: POKE 53277.PEEK(53271} OR 2tN where N is the number ofthe sprite.Sprites 167 N otice how the black sprite is made to move (in and out' of the coloured bars. the bits appropriate to those sprites in the SPRITE TO SPRITE COLLISION REGISTER at location 53278 . When a collision between sprites is detected. EXPANDING SPRITES There are two further registers associated with sprites which allow you to expand them in the X and Y directions. COLLISION DETECTION Another useful feature of sprites is that you can determine when one sprite comes into contact with another sprite or with other data on the screen. a 1 means it is twice the size.PEEK(53271} 255-2tN AND Try these commands in immediate mode to see their effect. Each bit in these two registers controls the size of one sprite in each direction .PEEK(53277} AND Ydirection: 255-2tN POKE 53271. To revert to normal size : Xdirection: POKE 53277. PEEK (53277) OR 2tN Ydirection: POKE 53271. To expand asprite.a 0 me ans the sprite is normal size in that direction. whilst the white one always has higher priority than the data and therefore passes in front of all the coloured bars.

trying to avoid the obstacles strewn along the course whilst keeping on the track: CRESTARUN 20 100 110 120 130 140 150 160 170 180 185 190 200 210 220 230 240 250 260 270 GOSUB 500 GET K$:IF K$="" THEN 160 IF K$="{CD}" THEN X=X-5 IF K$="{CR}" THEN X=X+5 IF X>250 THEN X=O:POKE 53264. You are in control of a toboggan hurtling down the Cresta Run.Part 1 168 are set to 1. You move Ieft and right using the two cursor keys.1 :GOTO 150 IF x=o THEN X=255:POKE 53264.0 POKE 53248. The following short game shows this happen.The Commodore 64 Omnibus .7 IF S<SS THEN 280 IF DI=O THEN 270 I=I-l:IF I=O THEN DI=l-DI GOTO 280 I=I+l:IF I=BB THEN S=O:DI=l-DI . Collisions between sprites and screen data are indicated in the SPRITE TO DATA COLLISION REGISTER at Iocation 53279. A collision is deemed to have occured when any non-zerofart of asprite overlaps another non zero-part 0 data.X OB=INT(RND(0)*4*DF) OP=INT(RND(O)*WD) IF OB=l THEN O$="{BLK}t{WHT}" :GOTO 190 0$="" PRINT TAB(10+I)"e"SPC(OP)0$ SPC(WD-OP)"e" S=S+l:T=T+l IF PEEK(53279)=1 THEN POKE 53287.11:H=H+l:GOT0230 POKE 53287. and will remain so until that register is examined with a PEEK command.

255. The collision is detected in line 210 which . X=140:POKE 53248. DATA DATA 0.255.0.Sprites 280 290 300 310 320 330 340 350 360 500 510 520 530 540 550 560 570 580 590 600 610 620 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 169 IF S=O THEN SS=INT(RND(O)*DF* 15) IF T=300 THEN 310 GOTO 100 PRINT"{CLS} GAME OVER" PRINT:PRINT"YOUR SCORE WAS "INT«T-H)/T*100)"%" PRINT:PRINT"ANOTHER GO (Y/N)?" GET A$:IF A$="" THEN 340 IF A$="Y" THEN RUN END PRINT"{CLS){WHT}" INPUT"DIFFICULTY (l=EASY TO 5=HARD) "iDF IF DF<l OR DF>5 THEN 500 DF=6-DF WD=10:SS=50:BB=10 FOR J=O TO 63:READ D POKE 832+J.0.128 DATA 0.100 POKE 53287.X POKE 53249.128 DATA 0.128 DATA DATA 0.D:NEXT J POKE 2040. DATA 0.156.128 DATA 0.0.0 N otice how the colour of the toboggan changes whenever it 'hits' the walls of the track or an obstacle. RETURN DATA 0.0 DATA DATA 0.7 POKE 53269.

The progr am reHes on the screen scroll ing to give the illusi on ofmo veme nt. using a comm and such as: POKE 5327 6. as show n in the table on the next page. To selec t multi colou r mode for aspr ite.Part 1 incre ments the count er H (the numb er of collisions) and chang es the colou r of Spri te 0 (the tobog gan) to grey. but horiz ontal resol ution is halve d. That is Multi Colou r Sprite s can be in up to four differ ent colou rs. The other thing to notice about the progr am is that the tobog gan can only move horiz ontall y . so multi colou r sprite s are 12 * 21 pixels in size. since this is perfo rmed by the opera ting syste m much more quick ly then we could with a BASI C progr am. The Bit Pair can be select ively colou red using one of the four comb inatio ns of 0 and 1. MULTI COLOUR SPRITES In the same way that we can have multi colou r chara cters. and the tobog gan rema ins grey for as long as it is in conta ct with the obsta cle. we can choose any sprite to be in multi colou r mode . the appro priate bit in the SPRI TE MUL TI COLO UR REGI STER must be set to 1.each colou red tpixe l' in fact consi sts of two pixels side by side. with the same trade off of resolu tion for colou r as with multi colou r chara cters. The Sprit e to Data collis ion regis ter is check ed each time the track is move d. each pair being called a Bit Pair. In multi colou r mode .170 The Comm odore 64 Omnib us .PEE K(53 276) OR 2tN . sprite data is interp reted differ ently in that a pair of bits is requi red to speci fy a pixel .it is the track which move s.

Multicolour Sprite Grid . To return the sprite to standard mode this bit must be set to 0: POKE 53276.Sprites BIT PAIR COLOUR 00 Screen Colour 01 Multi Colour Register 0 10 Sprite Colour Register 11 Multi Colour Register 1 171 N is the number ofthe sprite to be changed to multi colour mode.PEEK(53276) AND 255-2tN Multi colour sprites behave in exactly the same way as standard sprites .the only difference is in the way they are defined. Let's take an example to make this clear.

but remember that each pixel is now defined by two squares of the grid. We can allocate each of these colours to a particular register: BACKGROUND SCREEN COLOUR 00 FACE SPRITE COLOUR 10 EYES REGISTER 0 01 LIPS REGISTER 1 11 The numbers in the right hand column are the bit pairs which specify the register from which the colour of a given pixel is drawn.0 FOR 1=0 TO 63:READ D POKE 832+1. In order to see the difference between multi colour mode sprites and the standard variety here is a short program which displays the multicoloured face: 5 10 20 PR1NT "{CLS}":POKE 53281. This information is converted into 63 bytes of data in the usual way. This means that all pixels containing the bit pair 11 will be displayed in the colour currently held in Multi Colour register 1.The Commodore 64 Omnibus . Opposi te is a design for a face which we will turn into a multi colour sprite.Part 1 172 CREATING A MULTI COLOUR SPRITE We can use the same 24 by 21 grid we used earlier to plan the design. Notice that the pixels are twice the size of those in our earlier designs and that there are four different types of shading corresponding to the four different colours available for multi colour sprites.D:NEXT . We can now fill each area ofthe design with the bit pairs appropriate to their colour. whilst all those set to 00 will be in the current screen colour.

Sprites EJ EJ Screen Colour: 173 Blue Multicolour Sprite Colour 0: White ~ Normal Sprite Colour: Green [22J Multicolour Sprite Colour 1: Red Multicolour Sprite 30 40 50 60 FOR I=2040 TO 2047 POKE I.13:NEXT POKE 53276.255 FOR I=O TO 15 . DATA 85. For instance.170 DATA 170.94.168 DATA 170.1 POKE 53286. POKE 53269.136.22 DATA 165.42.170. our first character would look much more convincing if 4is mouth opened and closed as he moved.160.181 DATA 85. simple animation is just a matter of setting up several blocks of data corresponding to the various stages ofmovement. 1 174 70 80 90 100 110 120 130 140 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 POKE 53248+I. DATA 128.0.85. ANIMATION Because of the way in which the VIC II chip is directed to the start of a block of sprite data. DATA 170.0. a word about animation. DATA and so the illusion of movement is easily created.255 DATA 8. Here is a pro gram which doesjust that and moves the sprite around the screen: 10 20 PRINT"{CLS}" POKE 53281.15 .255. then changing the value ofthe sprite pointer to point to each block in turn.170 DATA 168.255 DATA 250.50+(10*I) NEXT I FOR I=O TO 7 POKE 53287+I.40.42.0 Finally. The change in the appearance is instantaneous.5+I NEXT I POKE 53285.The Commodore 64 Omnibus .181. and his mouth always faced his direction of motion.173.168 DATA 10.

X IF x=o AND PEEK(53264)=0 THEN 700 IF x=o THEN X=255:POKE 53264.X IF X=90 AND PEEK(53264)=1 THEN 700 X = X+5 IF X=255 THEN X=O:POKE 53264.14-«MODE=1)*1) X = X-5 POKE 53248.1:POKE 3248.13 :POKE 53269.Sprites 30 40 50 100 110 130 135 140 145 150 155 160 165 170 180 500 510 520 530 540 550 560 570 600 610 620 630 640 650 660 700 997 998 175 FORI=OT0191:READ D:POKE 832+I .C FOR Y=50 TO 200 STEP 50 POKE 53249.1 IF Y=100 THENPOKE 53277.1 C=0:POKE53287.X IF X/15 = INT(X/15)THEN MODE = I-MODE GOTO 510 POKE 2040.Y GOSUB 500 IF Y=50 THEN POKE 53277.0 :POKE 53248.13-«MODE=1)*2) POKE 53248.0:END IF D=l THEN 600 POKE 2040.D :NEXT POKE 2040.0:POKE 53271.1 D=l-D C=C+2 POKE 53287.C NEXT Y POKE 53269.0: POKE 53277.1 IF Y=150 THEN POKE 53277.0 POKE 53271.X IF X/15=INT(X/15)THEN MODE = 1MODE GOTO 600 RETURN REM REM RIGHT FACING SPRITE . DATA 252.255.252 DATA 0.3.24 DATA DATA 224.0.248 DATA DATA 128.247.255 DATA DATA DATA 248.240 DATA 7.0 REM REM LEFT FACING SPRITE REM DATA 1 176 999 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1095 1097 1098 1099 2000 2010 2020 2030 2040 2050 2060 2070 2080 2090 2097 2098 2099 3000 3010 3020 3030 3040 3050 3060 3070 3080 3090 3095 REM DATA DATA 255.227 DATA DATA DATA 255.192 DATA 1.252 DATA DATA 1.3.255 DATA REM REM CLOSED MOUTH REM DATA DATA Commodore 64 Omnibus . DATA 248.3 DATA . DATA 255.63 DATA DATA 0.63 DATA 252.248.255 DATA 248.255 DATA 128.255 DATA 252.1.31 DATA 255.255.

is one with which your computer can assist. Lines 500 to 700 move the sprite across the screen and elose and open the mouth.13:POKE53281.Sprites 177 Lines 10 to 50 set up the various sprite registers. save the data on tape and many other useful things. SPRITE CREATION The process of defining sprites is very laborious. and.20). depending upon its position down the screen. and POKE the data into the cassette buffer. so it's weIl worth persevering in typing it all in! 1 2 3 4 5 6 7 10 20 30 40 50 60 93 94 REM ***************** REM * * REM * SPRITE EDITOR * REM * * REM ***************** REM REM DIM D%(23. and expand the sprite and change its colour. Lines 100 to 200 move the sprite down the screen by incrementing the Y position register in multiples of 50.12:PRINT I{GR3}" RS=53248:DS=12288:SN=0 B$=" {CU}":REM 37 SPACES MO=l REM REM ************** . The following program will allow you to create and modify your sprites. like user defined characters.DA%(64) CS=1065:CX=0:CY=0:CC=CS:CD%(0)= 43:CD%(1)=81 POKE53280.

0:REM MULTI COL.255:REM ENABLE POKE 53277.1:REM COLOUR POKE 2040+I.0:REM NO Y EXPANSION POKE 53276.52+(25*I):REM Y POS POKE 53287+I.0:REM NO X EXPANSION POKE 53271.255:REM X MSB POKE 53269.50:REM X POS POKE 53249+2*I. OFF PRINT SPC(6)"{RVS}P{ROF}ROGRAM {RVS}L{ROF}OAD {RVS}S{ROF}AVE" REM REM ****************** REM * * REM * KEYBOARD INPUT * REM * * REM ****************** .Part 1 95.178 The Commodore 64 Omnibus . 96 97 98 99 100 110 120 130 140 150 160 170 180 493 494 495 496 497 498 499 500 510 520 530 540 550 560 570 580 590 600 650 993 994 995 996 997 998 REM * * REM * PRINT GRID * REM * * REM ************** REM PRINT" {CLS}" G$=" ++++++++++++++++++++++++" FOR I=O TO 20 PRINT G$:NEXT I CD = PEEK(CS) PRINT "{HOM}" FOR I=l TO 8:PRINT TAB(32)I IF I<8 THEN PRINT:PRINT NEXT I REM REM *************************** REM * * REM * SET UP SPRITE REGISTERS * REM * * REM *************************** REM FOR I=O TO 7:REM DO EACH SPRITE POKE 53248+2*I.192+I:REM POINTERS NEXT I POKE 53264.

CD IF K$=" " THEN SD=l-SD:CD= CD%(SD) IF K$="P" THEN SA=56222:L=6: CO=2:GOSUB 1200:GOSUB 3000: CO=ll:GOSUB 1200 IF K$="L"THEN 4100 IF K$="S"THEN 4000 IF K>48 AND K<57 THEN GOSUB 2000 IF K>32 AND K<41 THEN GOSUB 2500 CC=CS+CX+(40*CY):D%(CX.Sprites 999 1000 1005 1010 1020 1030 1040 1060 1070 1090 1095 1100 1110 1120 1130 1200 1210 1493 1494 1495 1496 1497 1498 1499 1500 1510 1520 1530 1540 1600 179 REM GET K$:IF K$="" THEN 1500 K = ASC{K$) IF K$="{CR}" AND CX<23 THEN CX=CX+l:POKE CC.CD IF K$="{CD}" AND CY<20 THEN CY=CY+l:POKE CC.CY)=SD POKE CC.CD IF K$="{CL}" AND CX>O THEN CX=CX-l:POKE CC.CD IF K$="{CU}" AND CY>O THEN CY=CY-l:POKE CC.CO:NEXT:RETURN REM REM **************** REM * * REM * FLASH CURSOR * REM * * REM **************** REM CT = PEEK(CC) C%=(CT OR 128)-(CT AND 128) POKE CC.CD:GOTO 1000 FOR I=O TO L POKE SA+I.C% FOR I=O TO 100:NEXT GOTO 1000 PRINT SPC(6)"{RVS}P{ROF}ROGRAM {RVS}L{ROF}OAD {RVS}S{ROF}AVE" : RETURN .

0:NEXT I PRINT"{CU}"B$:GOSUB 1600: RETURN REM REM *************************** REM * * REM * CONVERT GRID TO DATA * REM * * REM *************************** REM I = O:FOR Y=O TO 20 FOR BYTE=O TO 2:DA%(I)=0 FOR BIT=O TO 7 .Part 1 180 1993 1994 1995 1996 1997 1998 1999 2000 2010 2020 2030 2493 2494 2495 2496 2497 2498 2499 2500 2510 2520 2530 2540 2550 2560 2993 2994 2995 2996 2997 2998 2999 3000 3010 3020 REM REM ******************** REM * * REM * SPRITE SELECTION * REM * * REM ******************** REM IF SN=O THEN 2020 POKE SS+54272.11 SN = K-48: SS=CS-88+(SN*120): POKE SS+54272.3 GOSUB 3500:RETURN REM REM ********************* REM * * REM * CLEAR SPRITE DATA * REM * * REM ********************* REM PRINT"{HOM}{22 * CD}" PRINT B$:PRINT" ARE YOU SURE ?" GETA$:IF A$="" THEN 2520 IF A$<> "Y" THEN PRINT"{CU}"B$: GOSUB 1600:RETURN PRINT"{CU}"B$:PRINT" CLEARING DATA" FOR 1=0 TO 63:POKE DS+((K33)*64)+I.The Commodore 64 Omnibus .

DA%(I): I=I+1 3050 NEXT BYTE 3060 NEXT Y 3120 RETURN 3493 REM 3494 REM ************************ 3495 REM * * 3496 REM * CONVERT DATA TO GRID * 3497 REM * * 3498 REM ************************ 3499 REM 3500 FOR I=O TO 63:DA%(I)=PEEK (DS+((SN-1)*64)+I):NEXT:I=0 3510 FOR y=o TO 20 3520 FOR BYTE=O TO 2 3525 N = DA%(I) 3530 FOR BIT=7 TO 0 STEP-1 3540 B2 = 2tBIT 3550 IF N .N$ 4025 PRINT"{CU}"B$"{CU}" .B2 >=0 THEN CH=81:N=NB2:GOTO 3570 3560 CH = 43 3570 POKE CS+(7-BIT)+(8*BYTE) +( 40*Y) .Sprites 181 3030DA%(I)=DA%(I)+(2t(7-BIT»*(PEEK(CS+(BIT)+(8*BYTE)+(40*Y» =81) 3040 NEXT BIT 3041 POKE DS+((SN-1)*64)+I.CH 3590 NEXT BIT:I = I+1:NEXT BYTE 3600 NEXT Y:RETURN 3993 REM 3994 REM ******************** 3995 REM * * 3996 REM * SAVE SPRITE DATA * 3997 REM * * 3998 REM ******************** 3999 REM 4000 PRINT"{HOM}{23 * CD}" 4010 PRINT B$ 4020 INPUT" FILE NAME".

and will contain random data when the program is first RUN.0. are displayed down the right hand edge of the display.1.N$ 4145 PRINT"{CU}"B$ 4150 FOR I=O TO 63 4151 GET#l. The eight sprites. numbered 1 to 8.1.D$ 4152 IF 0$ ='''' THEN 0$ = CHR$ (0) 4153 DA%(I) = ASC(D$) 4155 POKE DS+(SN-1)*64+I. To clear any sprite data area.Part 1 4030 OPEN 1. created.N$ 4035 PRINT"{CU}"B$ 4040 FOR I=O TO 63:PRINT#1. hold .CHR$ (DA%(I»i: NEXT 4050 PRINT"{CU}"B$"{CD}" 4060 CLOSE 1 4070 GOTO 650 4093 REM 4094 REM ******************** 4095 REM * * 4096 REM * LOAD SPRITE DATA * 4097 REM * * 4098 REM ******************** 4099 REM 4100 PRINT "{HOM}{23 * CD}" 4110 PRINT B$ 4120 INPUT" WHICH SPRITE (1-8)"iSN 4122 PRINT"{CU}"B$ 4125 INPUT" FILE NAME"iN$ 4130 PRINT"{CU}"B$"{CU}{CU}" 4140 OPEN 1.182 The Commodore 64 Omnibus .DA%(I):NEXT 4157 PRINT"{CU}"B$"{CD}" 4160 CLOSE 1 4170 GOTO 650 How to use the pro gram The program draws a large 24 by 21 grid on the left hand side of the screen upon which sprites are .1.

. When loaded. Sprites can be SAVEd on tape and LOADed by pressing 'S' or 'L' respectively. the current sprite data must be loaded into the grid by pressing the appropriate number key. the sprite will be displayed on the grid ready for editing. the appropriate data is placed in the sprite data area by pressing 'P'. The flashing cursor is moved around the grid with the cursor keys and can be set to erase or plot 'pixels' by using the space bar which toggles between the two options. and following the prompts displayed on the screen.Sprites 183 down the SHIFT key and press the sprite number key. To create asprite. When asprite has been created.

and to LOAD and RUN programs from tape. 'N AME' should be the name of the pro gram you wish to load. Start the tape by pressing the PLAY key. PROGRAMS ON TAPE To load a program from tape. put the cassette in the tape unit and rewind it to the beginning. the tape will stop moving and the message: FOUND NAME will be displayed on the screen. disk or plug-in cartridge. When the pro gram is reached.CHAPTER 15 PERMANENT STORAGE The 64 is able to store pro grams onto cassette tapes or floppy disks. Tapes and disks mayaIso be used to store data for future use. If you want the first program on the tapejust type: LOAD 1111 The 64 will respond to these commands by displaying the message: PRESS PLAY ON TAPE. The screen will go blank and the tape will start to move. Type the command: LOAD "NAME" and press RETURN. After a few seconds .

You can cut short the pause by pressing the Commodore key (C=) when the pro gram name is displayed. When the program has been LOADed it will start running automatically. Rewind the tape to the beginning ofthe program. The name you use for the SA VEd pro gram can be any combination of characters up to a maximum length of16. To LOAD and RUN the first pro gram on a cassette. use the VERIFY command.Permanent Storage 185 the screen will go blank again and the program will be loaded. Type the command: SAVE "NAME" The computer will respond with: PRESS PLAY AND RECORD ONTAPE Start the tape by pressing the RECORD and PLA Y keys together. and will then display the name of the first program found. hold down a SHIFT key and press RUN/STOP. Saving Pro grams To save the program in the computer onto tape. put a blank cassette into the tape unit and wind it forwards past the transparent leader. press RUN/STOP. Checking Pro grams To check that a pro gram has been saved accurately. and type: VERIFY "NAME" The message: . and the program will be SA VEd. If you do not wish to load the program. The screen will go blank. The 64 will again ask you to start the tape.

or '?VERIFY ERROR' if the two did not match. the message 'OK' will be displayed if the two programs were identical. Start the tape. 8 and press RETURN.186 The Commodore 64 Omnibus . put the disk into the drive and elose the door. To load a program from disk. 8 . When the program is found. PROGRAMS ON DISK Loading and saving programs from disk is very similar to using the tape. Type the command: LOAD "NAME". type: SAVE "NAME".8' added which instructs the 64 to use the disk drive instead of the cassette uni t. and the program on tape will be compared with the pro gram in the computer. with the suffix '. After a few seconds the screen will blank again. The same commands are used. and the screen will go blank while the 64 searches for the program. The computer will respond wi th the messages: SEARCHING FOR NAME LOADING NAME and then READY when the process is complete. When the pro gram has been checked.Part 1 PRESS PLA Y ON TAPE will be displayed on the screen. To save a program onto the disk. the message: FOUND NAME is displayed.

The VE RIFY command can also be used wi th disks. or ?VERIFY ERROR if the two were different. and can be in numericalor string form. 8 The 64 will display: SEARCHING FOR NAME VERIFYING and either OK if the program on disk matched the one in the 64.Permanent Storage 187 The 64 will display: SAVING NAME and READY when it has finished. The data is stored in files. you must switch off the 64. Then plug the cartridge into the socket on the right at the rear of the machine. Chapter 24. type: VERIFY 11 NAME 11 . FILE HANDLING As wen as loading and saving programs. First. To create a file. or it may be damaged. and switch on again. Follow the instructions enclosed with the cartridge to start the pro gram. the command OPEN is used: . To verify a program. Full details of all aspects of disk use are gi ven in Part 2. the Commodore 64 can use the cassette uni t to store and reload data generated by programs. PROGRAMS ON CARTRIDGES Programs on cartridges are the easiest of all to use.

if S is one. which is always 1 for the tape unit . The command must be followed by the file number of the file to which the data is to be written: PRINT#l.188 The Commodore 64 Omnibus . To write data to the tape the command PRINT# is used. S is called a secondary address. "NAME" The parameter F is the file number. . whereas when writing to a tape file. When reading a file. The file number must be specified when using these commands also. CLOSE is used to terminate the use of a file. D. There are two commands which read data from files: INPUT# and GET#. and can have three meanings when using tape files. the file data is to be read from the tape. and if S is two. data is to be written to the tape. whereas GET# reads single bytes from the tape. data is written to the tape and a special ((end of tape" marker is wri tten at the end of the file. D is the device number. a reference number used to identify which file is being used by each file command (there may be a number of files in use at the same time). except that data is written to the tape instead of to the screen. the CLOSE command writes an ((End of File" or ((End ofTape" marker onto the tape.other peripherals have different numbers. Again. X would write the value of the variable X to file number 1. S. This is very similar to the PRINT command. the commands are similar to their keyboard reading counterparts. INPUT# reads a number of bytes of data terminating in a carriage return.Part 1 OPEN F. If S is zero. CLOSE simply closes the input channel.

1. A$ CLOSE 1 PRINT A$ Put a blank tape into the tape unit and wind it forwards past the transparent leader tape.Permanent Storage 189 The following short pro gram shows the use of OPEN. 0. and the data printed on the screen. INPUT# and CLOSE. and the file will be created and the data stored. 1. "TEST" PRINT#l. Without punctuation. 10 20 30 40 100 110 120 130 OPEN 1. This technique may be used to store any amount of data onto tape. PRINT#. When you set the tape going the data file will be OPENed and read. "TEST" INPUT#l. Punctuation marks . RUN the program. Start the tape. PRINT# puts a carriage return character after each item of data written to the tape. The program will stop with the message nBREAK IN 40". and the 64 will display the message: PRESS PLAY AND RECORD ON TAPE as happens when SA VEing programs.commas and semi-colons may be used with PRINT# as with PRINT. Y ou can save numerical data as weIl as strings in the same way. Rewind the tape and type RUN 100. and it these carriage returns are used by the INPUT# statement to distinguish between . 1. The message PR ESS PLA Y ON TAPE is displayed. "THIS IS A TEST FILE" CLOSE 1 STOP OPEN 3.

This method is used in the Character Generator program in Chapter 12 to save character sets onto tape. is a system variable which provides information about tape files. The command is most often used to list data to a printer. then writing them to the tape with PRINT#.2 OK 4 SHORT BLOCK 8 LONG BLOCK 16 UNRECOVERABLE READ ERROR 32 CHECKSUM ERROR 64 END OF FILE -128 END OF TAPE One last peripheral handling instruction is CMD. If you need to store single byte numbers. as all the space is taken up by data with no separating characters. OTHER PERIPHERAL COMMANDS STATUS. This diverts the normal screen output to a specified output channel or data file. Using commas or semicolons suppresses the carriage returns with the result that the INPUT# statement will not read the data properly. which are shown in the table: STATUS MEANING 1.Part 1 adjacent items of data. The variable has eight possible meanings.190 The Commodore 64 Omnibus . but can also be used to record programs listings on tape. and reading them with GET# makes very efficient use ofthe tape. reading single bytes from the file without regard for carriage returns or any other markers. perhaps . or ST. This is where GET# is useful.

(All the programs in this book were transferred to a word processor in this way). and to search through the index for specific i tems. The program is written as an address book. DATAFILE This program uses the file handling commands to maintain a simple database on tape. As well as loading and saving the data.Permanent Storage 191 for incorporation in a word processor document. To list a program to a printer use the command sequence: OPEN 1. but there are many other applications. "LISTING" eMD 3 LIST eLOSE 3 Pro gram listings saved in this way can not be reloaded and RUN. the program allows you to insert and remove entries. Similarly. 1 2 3 4 5 REM REM REM REM REM ***************** * * * 64 DATAFILE * * * ***************** . 1. 1. a program can be listed to a tape file by the sequence: OPEN 3. 4 eMD 1 LIST eLOSE 1 The listing will be diverted from the screen to the printer. so always make sure you have a copy ofthe program SAVEd in the normal way.

Part 1 192 10 GOSUB 50000: 90 92 94 96 98 REM **************** REM * * REM * FIRST MENU * REM * * REM **************** 100 230 240 900 PRINT "{CLS}{CD} {RVS} 64 DATAFILE {ROF}" PRINT TAB(10) "{CD}{CD}{RVS}L{ROF}OAD FILE PRINT TAB(10) "{CD}{CD}{RVS}N{ROF}EW FILE PRINT TAB(10)"{CD}{CD}{RVS}F1{ROF}: END" GET K$: IF K$="" THEN 200 IF K$="L" THEN GOSUB 10000: GOSUB 1000: GOTO 100 IF K$="N" THEN GOSUB 11000: GOSUB 1000: GOTO 100 IF K$ <> "{FI}" THEN 200 PRINT "{CLS}": END IF EX=l THEN RETURN 990 992 994 996 998 REM ****************** REM * * REM * INSPECT FILE * REM * * REM ****************** 1000 GOSUB 22000: REM PRINT SCREEN HEADER PRINT: PRINT: PRINT TAB(10) "{RVS}E{ROF}NTER NEW DATA" PRINT: PRINT TAB(10) "{RVS}F{ROF}IND ITEM" PRINT: PRINT TAB(10) "{RVS}L{ROF}IST ALL ITEMS" 110 120 130 200 210 220 1010 1020 1030 REM SET UP .The Commodore 64 Omnibus .

Permanent Storage 1040 193 1150 PRINT: PRINT TAB(10) "{RVS}S{ROF}AVE FILE TO TAPE" PRINT: PRINT TAB(10) "{RVS}Fl{ROF}: RETURN TO FIRST MENU" GET K$: IFK$="" THEN 1100 IF K$="E" THEN GOSUB 2000: GOTO 1000 IF K$="F" THEN GOSUB 3000: GOTO 1000 IF K$="L" THEN GOSUB 4000: GOTO 1000 IF K$="S" THEN EX=O: GOSUB 5000: GOTO 900 IF K$ <> "{Fl}" THEN 1100 1190 1192 1194 REM REM *** SAFETY CHECK *** REM 1200 1250 1260 GOSUB 22000: REM PRINT SCREEN HEAOER PRINT "{CO}{CO} {RVS}OO YOU WANT TO SAVE THE FILE?{ROF}" PRINT TAB(10) "{CO}{CO}{RVS}Y{ROF}ES" PRINT TAB(10) "{CO}{RVS}N{ROF}O" GET K$: IF K$="" THEN 1230 IF K$="Y" THEN GOSUB 5000: GOTO 1000 IF K$="N" THEN RETURN GOTO 1230 1990 1992 1994 1996 1998 REM ****************** REM * * REM * ENTER NEW OATA * REM * * REM ****************** 1050 1100 1110 1120 1130 1140 1210 1220 1225 1230 1240 .

I) NEXT I P = P+1 2190 2192 2194 REM REM *** DISPLAY NEW ITEM *** REM 2200 2210 2220 2230 2250 2260 2270 2280 2300 GOSUB 22000: REM SCREEN HEADER ID = P-1 GOSUB 20000: REM DISPLAY ITEM PRINT "{CD}{CD} PRESS {RVS}RETURN{ROF} TO ACCEPT THIS ITEM" PRINT" OR {RVS}DEL{ROF} TO DELETE IT" GET K$: IF K$="" THEN2250 IF K$=RET$ THEN RETURN IF K$ <> DEL$ THEN 2250 GOSUB 21000: REM DELETE ITEM RETURN 2990 2992 REM ************* REM * * 2010 2020 2240 .Part 1 194 2000 2030 IF P < EL THEN 2100: REM CHECK SPACE PRINT "{CLS}" TAB(10) "{CD}{CD}{CD}{RVS} INDEX FULL {ROF}" W=3: GOSUB 30000: REM 3 SECOND PAUSE RETURN 2090 2092 2094 REM REM *** ADD NEW ITEM *** REM 2100 2110 2120 2130 2140 2150 GOSUB 22000: REM SCREEN HEADER PRINT: PRINT: PRINT " ENTER DATA{CD}" FOR I=O TO FLDS PRINT F$(I)~: INPUT A$(P.The Commodore 64 Omnibus .

F$(I) NEXT I GET K$: IF K$="" THEN 3100 IF ASC(K$) < 49 OR ASC(K$) > 49+FLDS THEN 3100 F = ASC(K$)-49 PRINT "{CLS}{CD}{CD} SEARCHING .F)=FI$ THEN FP(FF)=I: FF=FF+1 NEXT I PRINT "{CLS}{CD}{CD}{CD} "FF " ITEMS FOUND" IF FF=O THEN W=3: GOSUB 30000: RETURN: REM WAIT 3 SECONDS 3020 3030 3040 3050 3060 3100 3110 3120 3130 3320 3400 3410 3490 3492 3494 REM REM ** DISPLAY FOUND ITEMS ** REM ... FOR 1=0 TO FLDS PRINT TAB(10) 1+1. " REM CLEAR FOUND ITEM POINTER FOR 1=0 TO P FP(I) = -1 NEXT FF=O 3290 3292 3294 REM REM *** DO THE SEARCH *** REM 3300 3310 FOR 1=0 TO P IF A$(I.Permanent Storage 195 2994 2996 2998 REM * FIND ITEM * REM * * REM ************* 3000 3010 3190 3200 3210 3220 3230 GOSUB 22000: REM SCREEN HEADER IF P=O THEN 3700: REM CHECK FOR ENTRIES PRINT: INPUT "FIND". FI$ PRINT" {CD}IN:".

The Commodore 64 Omnibus .Part 1 196 3600 3610 3620 FOR I=O TO FF-1 ID = FP(I) GOSUB 20000: REM DISPLAY ITEM PRINT "{CD} PRESS {RVS}N{ROF} FOR NEXT ITEM" PRINT "{CD} OR {RVS}DEL{ROF} TO DELETE THIS ONE" GET K$: IF K$="" THEN 3540 IF K$="N" THEN 3610 IF K$ <> DEL$ THEN 3540 GOSUB 21000: REM DELETE ITEM FOR II=O TO FF-1 FP(II) = FP(II)-l: REM RESET FOUND POINTERS NEXT II NEXT I RETURN 3690 3692 3694 REM REM IF NO ITEMS PRINT MESSAGE REM 3700 3720 PRINT TAB(5) "{CD}{RVS} THERE ARE NO ITEMS TO FIND! {ROF}" W=3: GOSUB 30000: REM WAIT 3 SECONDS RETURN 3990 3992 3994 3996 3998 REM ******************** REM * * REM * LIST ALL ENTRIES * REM * * REM ******************** 4000 4010 4020 GOSUB 22000: REM SCREEN HEADER PRINT "{CD}{CD} LIST" IF P=O THEN 4300: REM CHECK IF ANY ENTRIES REM DISPLAY ENTRIES ID=O GOSUB 20000: REM DISPLAY ITEM 3500 3510 3520 3530 3535 3540 3550 3560 3570 3580 3590 3710 4090 4100 4110 .

FL$ 4130 4140 4150 4160 4170 4180 4310 5030 5035 5040 *** IF NO ENTRIES *** *** PRINT MESSAGE *** ." PRINT: PRINT " {RVS}DEL{ROF} TO DELETE THIS ONE" PRINT: PRINT " OR {RVS}Fl{ROF} TO END GET K$: IF K$="" THEN 4150 IF K$=DEL$ THEN GOSUB 21000: GOTO 4180: REM DELETE ITEM ID = ID+l IF K$ <> "{Fl}" AND ID<P THEN 4110 RETURN 4290 4292 4293 4294 REM REM REM REM 4300 4320 PRINT TAB(5)"{CD}{CD}{RVS} THERE IS NOTHING TO LIST {ROF}" W=3: GOSUB 30000: REM WAIT 3 SECS RETURN 4990 4992 4994 4996 4998 REM ********************* REM * * REM * SAVE FILE TO TAPE * REM * * REM ********************* 5000 5010 5020 GOSUB 22000: REM SCREEN HEADER PRINT "{CD}{CD} SAVE FILE" PRINT: PRINT: INPUT " FILE NAME".Permanent Storage 4120 197 4200 PRINT: PRINT "{CD} PRESS {RVS}N{ROF} FOR NEXT ITEM. 1. 1. FL~ PRINT"{CD}{CD}PREPARE CASSETTE THEN PRESS {RVS}RETURN{ROF} GET K$: IF K$ <> RET$ THEN 5035 OPEN 1.

JJ) 10110 NEXT JJ 10120 P=P+l 10130 IF P<EL AND ST<>64 THEN 10080 10140 CLOSE 1 10200 RETURN 10990 REM ************ .Part 1 198 5120 5130 5140 5150 FOR II=O TO P-l FOR JJ=O TO FLDS PRINT#l. A$(P. II CLOSE 1 PRINT "{CD} PRESS {RVS}C{ROF} TO CONTINUE" PRINT "{CD} OR {RVS}Fl{ROF} TO END" GET K$: IF K$="" THEN 5120 IF K$="C" THEN RETURN IF K$="{Fl}" THEN EX=l: RETURN GOTO 5120 9990 9992 9994 9996 9998 REM *********************** REM * * REM * LOAD FILE FROM TAPE * REM * * REM *********************** 5050 5060 5070 5080 5090 5100 5110 10000 PRINT "{CLS}{CD} {RVS} 64 DATAFILE {ROF}" 10010 PRINT "{CD}{CD} LOAD FILE" 10020 FL$="" 10030 PRINT: PRINT: INPUT " FILE NAME"iFL$ 10040 PRINT"{CD}{CD} SET UP CASSETTE THEN PRESS {RVS}RETURN{ROF}" 10050 GET K$: IF K$ <> RET$ THEN 10050 10060 OPEN 1. A$(II. FL$ 10070 P=O 10080 FOR JJ=O TO FLDS 10090 INPUT#l. 0. 1.JJ) NEXT JJ.The Commodore 64 Omnibus .

JJ) 21040 NEXT JJ.JJ) = A$(II+l.J J ) = "" 11050 NEXT JJ. II 21050 P = P-l .II) NEXT II RETURN 20990 20992 20994 20996 20998 REM REM REM REM REM ****************** * * * DELETE AN ITEM * * * ****************** 21000 PRINT"{CD}{RVS}DELETING THIS ITEM{ROF}" 21010 FOR II=ID TO P-l 21020 FOR JJ=O TO FLDS 21030 A$(II.Permanent Storage 10992 10994 10996 10998 REM REM REM REM 199 * * * NEW FILE * * * ************ 11000 PRINT "{CLS}{CD} {RVS} 64 DATAFILE {ROF}" 11010 PRINT "{CD}{CD} NEW FILE 11020 FOR II=O TO EL 11030 FOR JJ=O TO FLDS 11040 A$ ( I I . II 11060 P=O 11100 RETURN ******************* * * * DISPLAY AN ITEM * * * ******************* 19990 19992 19994 19996 19998 REM REM REM REM REM 20000 20010 20020 20030 20040 20050 GOSUB 22000: REM SCREEN HEADER PRINT: PRINT " " A$(ID. 0) FOR II=l TO FLDS PRINT: PRINT TAB(5) A$(ID.

The Commodore 64 Omnibus . FLDS) OlM FP(EL) ****************** * * * INITIAL SET-UP * * * ****************** .Part 1 200 21060 PRINT"{CD}ITEM DELETED" 21070 RETURN 21990 21992 21994 21996 21998 REM REM REM REM REM ***************** * * * SCREEN HEADER * * * ***************** 22000 PRINT "{CLS}{CD} {RVS} 64 DATAFILE {ROF}" TAB(26) P " ENTRIES" 22010 RETURN 29990 29992 29994 29996 29998 REM REM REM REM REM ***************** * * * WAIT ROUTINE * * * ***************** 30000 TI$="OOOOOO" 30010 IF TI < W*60 THEN 30010 30020 RETURN 49990 49992 49994 49996 49998 REM REM REM REM REM 50000 50010 50020 50030 50040 50050 50060 50070 50080 50100 50110 EL = 100 FLDS = 6 F$(O) = "SURNAME" F$(l) = "FIRST NAME" F$(2) = "HOUSE AND STREET" F$(3) = "TOWN" F$(4) = "COUNTY" F$(5) = "POST CODE" F$(6) = "PHONE NUMBER" OlM A$(EL.

240 display an initial menu offering the options: Load a file from tape Create a new file Stop the program Pressing N for New or L for Load carries out the selected task and then subroutine 1000 (lNSPECT FILE) is called. A list of options is displayed.Permanent Storage 201 50200 RET$ = CHR$(13) 50210 DEL$ = CHR$(20) 50300 RETURN Pro gram Description The program is controlled using menus.usually the first letter ofthe option title. This subroutine is the heart ofthe program. Lines 100 . offering the options: Enter new data Find an i tem of data List all the i tems Save the file on tape Return to the first menu . A second menu is displayed. A main menu routine calls a number of subroutines which are independent of each other and perform different data-management tasks: entering new data. and you select the one you want by pressing the appropriate key . listing the data and so on. The program is written in modules. The first instruction of the pro gram calls the subroutine at 50000 which sets up the array in which the data is stored and the other main variables of the program.

DELETE ITEM (21000) deletes an entry.202 The Commodore 64 Omnibus . FIND ITEM (3000) searches for specified items.Part 1 and the appropriate subroutine is called when an item is selected. The file is stored in the array A$. LOAD FILE (10000) loads a file from the tape. The subsidiary routines ofthe program are: ENTER NEW DATA (2000) adds new data to the file. The other main variables usedare: P Pointer to the first free entry (and therefore also a count of the number of entries in the file). If F1 is pressed the user is asked whether the file should be saved on the tape before the program returns to the first menu. SCREEN HEADER (22000) prints a message at the top of the screen. EL The maximum number of entries. SAVE FILE (5000) saves the file on tape. NEW FILE (11000) blanks out the file and sets the entry counter (P) to zero. which is dimensioned in 50100. LIST ALL ITEMS (4000) lists all the entries in the file. . DISPLAY ITEM (20000) displays one entry of the file.

Ifyou want to add more features they may easily be 'plugged in'. FF The number of entries found in FIND ITEM. F$() The names of the fields. . change the names of the fields in lines 50020 onwards. FL$ The filename when loading or saving the data. I. To alter the pro gram to store different 66) could be added as subroutine 6000 by adding two lines to INSPECT FILE to display an extra menu item and call the subroutine. a routine to sort the entries into alphabetical order (perhaps based on the string sorting pro gram in Chapter 7 . ID The item to be displayed by DISPLAY ITEM.Permanent Storage 203 FLDS The number of 'fields' in each entry the second dimension of A$. If you alter the number of fields. J and JJ are used as counters in loops. TI. FP() Pointers to the found items. change FLDS in line 50010 to the number ofthe last field. For example.

Writi ng progr ams in mach ine code is .only memo ry (ROM) which interp ret the BASIC. For exam ple: .. MACHINE CODE SUBROUTINES The 64's micro proce ssor does not unde rstan d BASI C progr ams witho ut some assis tance . This chapt er decrib es some final BASIC comm ands which you will find usefu l as you write more ambit ious progr ams. but can be very worth while as mach ine code pro gram s run very much faster . You can enter mach ine code routin es from BASIC using the comm and SYS. and round s off with so me gener al advic e on how to wri te good progr ams. givin g the start addre ss in memo ry of the mach ine code routi ne. and Chap ters 19 to 21 give some powe rful routin es to exten d the 64's facilit ies.CHAPTER 16 ADV ANC ED TECHNIQUES The previ ous chapt ers cover all you need to write many pro gram s for your 64. BASIC progr ams can be run only becau se the 64 has some mach ine code pro gram s perm anen tly stored in read. it unde rstan ds a much crude r set of instru ction s called mach ine code or mach ine langu age. This chapt er introd uces the BASIC comm ands used to call mach ine code pro grams . Chap ter 18 descr ibes the use of mach ine code with the 64. more diffic ult than using BASIC. In Part 2.

60: POKE 786. At the end ofthe routine. The instruction is used like a BASIC function. For example. The address of the machine code to be run is defined by POKEing the low and high bytes ofthe start address into locations 785 and 786.Advanced Techniques 205 SYS 2048 will perform the same function as holding down the RUN/STOP key and pressing RESTORE. Machine code routines mayaiso be called by the instruction USR(). and: SYS 64738 will call the power-on setting up routines which clear the memory and print the start-up message. POKE 785. and then a previously defined machine code routine is called. 3 would cause subsequent USR() instructions to run the code starting at address 828 (the beginning of the cassette buffer). For example: 1000 A = USR(X) The number in brackets is stored in the 64's floating point accumulator. .it will destroy any program you have in the 64 at the time you use it. the number now in the floating point accumulator is returned to be stored in the variable. BE CAREFUL using this .

unless you plan your programs carefully. and after some practice you will find it fairly easy to write quite complicated routines. and only RUN/STOP and RESTORE will let you escape. Y (the Y is optional) and works as folIo ws: The contents of memory location MEM are exc1usively ORed with the variable Y. following a few simple rules.206 The Commodore 64 Omnibus . as for example when the computer is being used to control other equipment. . In other words. until a non-zero result is obtained. as it is on many machines. the 64 can lock up. the program is halted until the contents of a memory location become equal to a specfied number. To write complex programs successfully you must design them carefulIy. the 64 checks the memory location again.Part 1 THE WAIT COMMAND The WAlT command is not a pause command. WAlT is almost never used. DESIGNING GOOD PROGRAMS It is easy to write simple BASIC programs. X. and it has the disadvantage that the STOP key can not be used to end the pro gram while the WAlT command is in operation. and the result is ANDed with the variable X. However. WAlT is only useful when a very fast response is required. If the result is zero. The command has the format: WAIT MEM. when the program continues. This means that if the right answer is not found. The command does nothing that can not be acheived using PEEK and IF. a long program can get very messy and it can be very difficult to find all the mi stakes you are bound to make.

Key not valid CHECK KEY INPUT Sketch programs before writing the BASIC . For example. another to sort the data. Don't let this discourage you. a third to display results. and the flow through the program is easy to follow. and so on.207 Advanced Techniques The phrase Structured Programming is often used to describe these rules . While BASIC may lack the elegance ofsome other languages. all this me ans is that pro grams designed in accordance with these rules have a clear and logical structure. it is still possible to use it to write good programs by following the simple guidelines set out here: 1 Always plan out the program on paper. and divide the program into sections which correspond to the tasks. identifying the various tasks it will have to perform. you might have one section of program to get data from the keyboard. Decide what you want the program to do. You may be put off by hearing people say that BASIC is not a suitable language for structured programming.

5 Now type the program into the 64.208 The Commodore 64 Omnibus . wi th different seetions doing different tasks. beginning eaeh at a round number of so many thousands or tens of thousands. you will save a lot of time in getting your pro grams to work.writing them on paper and not typing straight into the 64. If you follow these guidelines. . and how it should be done. Try to write each seetion of the program so that it is as independent as possible of the other seetions. and you will have more time for aetually using them. Use a different set of line numbers for eaeh section. it will be much easier to find the more subtle errors. work out in more detail what eaeh seetion should be doing. 6 The program will not work! At this stage you can sort out all the SYNTAX ERRORs easily. 4 Write the BASIC routines for eaeh seetion ofthe pro gram . ~s you will be able to isolate the faulty bit of the program wi thou t diffieul ty.Part 1 2 It is often useful to dra w sketches of the way the tasks fi t together. and arrange the routines with a clear sequential flow from beginning to end: avoid jumping around with GOTO. If you have designed the program wen. 3 When you have got the overall structure of the program sorted out.



The kernal is responsible for all the functions needed to operate the 64 . arranging the memory.the basic interpreter mentioned above and the kernal. Both the interpreter and the kernal reserve some of the RAM for their own use.reading the keyboard. As the name suggests this pro gram interprets a BASIC program . .machine code. generally speaking in the first 2k of memory. this chapter deals with how the 64 stores and runs BASIC programs and shows how you can get more out of your 64 by understanding the techniques involved. Machine code is covered in more detaillater in the next chapter. the instructions for which are subroutines of the in terpreter program. Interpreter and Kernal ROMs The ROM memory in the 64 contains two machine code programs .converting it into aseries ofmachine actions.CHAPTER 17 BASIC AND HOW IT WORKS You are probably aware that the microprocessor in your 64 doesn't understand BASIC and needs to be programmed in its own language . operating the screen editor and so forth. To enable the 64 to run your BASIC pro grams it comes equipped with a large machine code pro gram called the BASIC interpreter.

if so. the line is inserted into the stored program. routines in the kernal take the character for each key press and store it in screen memory. When you press RETURN the entire line is copied from the screen into memory. To see this type in the following one line program and then enter the immediate mode commands following it. The BASIC interpreter reads the first few characters of the line to see if they form a line number and. BASIC pro grams are normally stored starting from location 2048. This system allows you to edit a line using the cursor keys without retyping the entire line.PEEK(Z): NEXT Z The display will look like the two left hand columns in the list below if you have typed the pro gram in exactly as it appears: ADDRESS CONTENTS COMMENT 2048 0 The first byte of a program is alwayszero 2049 19 Low byte oflink pointer 2050 8 High byte oflink pointer 2051 10 Low byte ofline number 2052 0 High byte ofline number .The Commodore 64 Omnibus .Part 2 212 HOW BASIC IS STOREO When you type in a line of a BASIC program. 10 PRINT "TEST": GOTO 10 FOR Z=2048 TO 2068:PRINT Z.

The contents of location 2048 are always zero if a BASIC program is stored in the 64. .BASIC and How it Works 2053 153 PRINT 2054 32 (space) 2055 34 " 2056 84 T 2057 69 E 2058 83 S 2059 84 T 2060 34 " 2061 58 2062 137 GOTO 2063 32 (space) 2064 49 1 2065 48 0 2066 0 Null 2067 0 Null 2068 0 Null 213 The comment to the right of each item in the list show what each location contributes to the program line.

Bytes 3 and 4 of the line (2051 and 2052) are the line number in the order low byte. 2049 and 2050.Part 2 214 Locations 2049 to 2065 hold the BASIC line and have the following functions: The first two bytes. indicate the position ofthe next line ofBASIC . This is because the 64 stores BASIC programs in a compressed form using a system of tokens whereby single byte codes are used to represent BASIC reserved words. so PRINT is the 25th item in the list.The Commodore 64 Omnibus . high byte. When you pressed RETURN and entered the program line the kernal program recognised the PRINT as BASIC reserved word by comparing it with a list kept in ROM starting at location 41118. The next byte contains the value 153 which is a shorthand for PRINT. NEXT Z . This method offers significant memory savings over storing commands as aseries of ASCII characters and also increases the speed at which pro grams run. In this case the number is 10 . represents the position ofthat command in the list with 128 added to it.more about this later. 10 15 20 30 40 50 60 70 REM DISPLAY RESERVED WORDS PRINT n{CLs}nCHR$(14) FOR Z=41118 TO 41250 A$ = CHR$(PEEK(Z» PRINT A$. IF ASC(A$)<91 THEN 70 N=N+1: PRINT CHR$(13). The following pro gram \ displays a section of the BASIC reserved word table from the ROM.N.that is 10 + 256*0. used to replace the PRINT command. The token 153.

since only the first two or three characters are checked by the interpreter. abbreviations and tokens is given in Appendix 3. which is the end ofthe program. making the system transparent to the user. 10. In this case they point to address 2067 (19 + 8*256 = 2067). . Location 2062 is another token. To see how the link pointer works. The next eight bytes in the list are simply the ASen representation of the characters you typed as part of the program line. this time 137 representing the GOTO command. The next two bytes are the line number following the GOTO command. but stored in their ASCn form. A full list of BASIC reserved words. The end of a BASIC program is indicated by three consecutive zeros. try adding the following line to the pro gram and examining memory locations 2066 to 2074. Let's return to the two bytes labelled ~link pointer' at the start of the list. and is followed by aspace. Another advantage of the token system is that it allows you to type BASIC commands in an abbreviated form. When a program is listed the tokens are converted back into the BASIC words they represent. These two bytes form the low and high bytes respectively of the address where the next line of the program is stored.BASIC and How it Works 215 You will see that PRINT is the 25th item in the list as mentioned above. not as a binary number.

Remember that the link pointer for line 10 pointed to location 2067? As before the third and fourth bytes con tain the low byte and the high byte ofthe line number. The program again terminates in three consecutive zeros. The diagram opposi te summarises how BASIC programs are stored.The Commodore 64 Omnibus . . and that location 2067 contains the low byte of the link pointer to the new end of the program. and 143 is the token for REM.Part 2 216 20 REM FOR Z=2066 TO 2074:PRINT Z. PEEK(Z): NEXT Z You will get a list like this: 2066 0 A null for the end ofline 10 2067 25 Low byte oflink pointer 2068 8 High byte of link pointer 2069 20 Low byte ofline number 2070 0 High byte ofline number 2071 143 REMtoken 2072 0 Null 2073 0 Null 2074 0 Null You should be able to see that there is now only one zero after line 10.

When a program is heing developed it is often useful to he ahle to <open up' gaps hetween lines to fit in new lines. BASIC UNE o BASIC UNE o Une No. and the next program allows you to do just that.BASIC and How if Works 217 Une No. Pointer to END OF PROGRAM The linked nature of a BASIC program Renumbering Pro grams We can make use of this know ledge to ren umher BASIC programs. 10 1 Pointerto Une No. 60000 REM RENUMBER 60010 INPUTISTART"iS 60020 INPUTIEND"iE 60030 INPUT"NEW START"iNS 60040INPUT I INCREMENT"iI 60050 A=2049 60060 Q=PEEK(A+2)+256*PEEK(A+3) 60070 IF Q<S THEN 61000 .

218 The Commodore 64 Omnibus . . Such a pro gram would not be impossible to write in BASIC but it would be quite slow! A possible way around this would be always to start your program numbering at line 10000 thereby ensuring that every GOSUB.Part 2 60080 IF Q>E THEN PRINT"FINISHED": END 60090 POKE A+2. refer to the table of BASIC commands and their tokens in Appendix 3.NS-INT(NS/256)*256 60095 POKE A+3. the entire BASIC pro gram would need to be moved up in memory by one byte to create space.INT(NS/256):NS=NS+I 61000 A=PEEK(A)+256*PEEK(A+1) 61010 IF A=O THEN END 61020 GOTO 60060 The program is numbered so it can form the last part of any program you are developing. Ifyou want to try this. GOSUB and THEN commands. This means that if a line number specified by a GOTO command is three figures long and is required to become a four figure number when the program is renumbered. GOTO or THEN reference was a five figure number. To wri te a program to alter these is more difficult because these line numbers are stored in their ASCII form and so occupy a varying number ofbytes. This is a very crude and simple renumbering program and doesn't take account of the line numbers following GOTO. Whenever you need to renumber simply type: RUN 60000 and enter the line numbers of the beginning and end of the program to be renumbered and the new start number and increment.

If incrementing the low byte of the character pointer causes an overflow. The character pointer is at locations $7 A and $7B (122 and 123) which form part of the CHRGET program. This process is carried out by a small machine code subroutine called CHRGET which is copied from ROM into zero page RAM (locations 115 to 138) when the 64 is switched on. so the program is . RETURN 115 117 119 121 124 126 128 130 132 133 135 136 138 E6 DO E6 AD C9 BO C9 FO 38 E9 38 E9 60 7A 02 7B B7 12 3A OA 20 EF 30 DO INC BNE INC LDA CMP BCS CMP BEQ SEC SBC SEC SBC RTS $7A $02 $7B $12B7 #$3A RETURN #$20 START #$30 #$DO The first operation of CHRGET is to increment the low byte of the character pointer . The RUN is interpreted as an immediate command and the appropriate part ofthe BASIC interpreter program is called. This subroutine initialises all pointers in zero page and closes all open channels. Below is a disassembly listing ofCHRGET: START FETCH . then the high byte is incremented. The first line ofthe program is then interpreted by loading it a character at a time into the accumulator and passing control to the appropriate subroutines as a command is found.two locations pointing to the next character of the BASIC text to be accessed.BASIC and How it Works 219 EXECUTING A BASIC PROGRAM A BASIC program stored in memory is oflittle use until it can be executed. This is achieved by typing RUN and pressing RETURN.

If the character is a colon (:).Part 2 selfmodifying! The section ofthe program labelled FETCH reads the character pointed to by the character pointer into the accumulator. b) Modify the next three bytes of CHRGET to perform a JSR to a subroutine which is a copy of . signifying another statement on this Une. This location is variable and the value in the listing above is what happened to be present in our 64 when the listing was created. then control jumps back to other routines in the interpreter which execute the command just fetched before returning for the next one. This technique can be used to add new commands to the BASIC language as the following simple example shows: ADDING NEW COMMANDS TO BASIC To add a new command to BASIC there are two steps to follow: a) Modify the first three bytes of CHRGET to perform a JSR to the routine which interprets and carries out the new command.220 The Commodore 64 Omnibus . This routine is very important since it gives you a chance to intercept the processing of BASIC pro grams and implement additional features. by replacing the code at the beginning of the routine by two JSR commands calling two of your own routines. If aspace is encountered then the next character is readin. The second routine simply copies that part of CHRGET overwritten by the JSR instructions while the first is the new user defined code.

store into .zero .1oop unti1 .set up SID .Jiffy c10ck .registers . START DELAY QUIET LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA LDA BPL LDA .turn off the . as a warning in case of errors.noise Even if you are not familiar wi th machine code you might recognise that the program simply sets up the necessary SID registers on channel one to make a tone. To incorporate the new command into BASIC. STA LDA STA RTS #37 54271 #100 54273 #15 54296 #54 54277 #168 54278 #33 54276 #122 162 162 DELAY #32 54276 #0 54296 . For example. Here is a short machine code routine which performs the function which could be called BEEP. In this example we . this machine code must be preceded by some code to recognise the new command.BASIC and How it Works 221 the first six bytes of the original CHRGET routine. suppose you wanted to add a command which caused a short tone to be emitted by the TV speaker. uses the jiffy dock to create a short pause and then turns the sound off.

to avoid confusing the issue with subroutines to decode the characters in a command.Y #6 INIT iModify the ifirst six ibytes of iCHRGET iroutine READ #35 RETURN BEEP COPY iget char iis it a #? $7A R2+1 $7B R2+2 R2+1 R2 R2+2 $0800 iCOPY $7A iand $7B iinto new iread iroutine & iget next icharacter $7A iCOPY of ino iyes! BEEP iupdate $7A iand $7B .222 The Commodore 64 Omnibus . Here is the program which modifies the CHRGET routine and incorporates a cBEEP' command into BASIC: 1 *=$COOO 10 CHRGET=115 90 ! 95 ! LDY 100 110 INIT LDA 120 STA INY 130 140 CPY BNE 150 RTS 160 190 191 200 PROG JSR CMP 205 BNE 210 JSR 220 JSR 225 RTS 230 RETURN 290 291 300 READ LDA STA 301 LDA 302 STA 303 INC 309 BNE 310 INC 320 LDA 330 R2 RTS 340 390 391 500 COPY INC #0 TABLE.Y CHRGET.Part 2 will use the # symbol as the new command.

192 5 . Z 20000 DATA BASIC and How it Works 510 520 530 EXIT 590 591 800 BEEP 805 810 815 820 825 830 835 840 845 850 855 860 865 870 DELAY 875 880 QUIET 885 890 895 900 990 991 1000 TABLE 1010 BNE EXIT INC $7B RTS LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA LDA BPL LDA STA LDA STA RTS :start of :CHRGET :routine #37 54271 #100 54273 #15 54296 #54 54277 #168 54278 #33 54276 #122 162 162 DELAY #32 54276 #0 54296 JSR PROG JSR COPY :new start iof CHRGET Below is a BASIC loader for the machine code: REM BASIC LOADER FOR BEEP COMMAND 10 FOR Z=49152 TO 49264 20 READ X:POKE Z. 28. 115.0.32.

133.141. To start the program type: SYS 49152 From now on every time a # is detected in the program.169.1.208. 5.35. the BEEP routine will be called. 165. 20060 DATA 192.212.212. 37.192.123. which will be overwritten by this program.208.141.122.i t must not be the first command on a Une. How the Program Works Upon initialisation the pro gram modifies the first six bytes ofthe CHRGET routine to read: JSR$COOE JSR$C032 . 32.230 20030 DATA 20020DATA 2 224 20010DATA 20050 DATA The # can be treated like any other BASIC command with one exception . .64 NOTE The code occupies some of the memory used by the graphics routines. 96.169 20040 DATA 15.2 12.19 Commodore 64 Omnibus .

the form in which they are stored in the 64 and their location in RAM. then adding code between lines 210 and 220 to compare the characters after the # with the commands in the table. VARIABLE STORAGE IN BASIC One of the things the BASIC interpreter must take care of is the handling of variables. It must decide where to store them and have an indication as to what type of variable they are. If a match was found then the appropriate subroutine would be called. If a # symbol is detected. and this is updated to keep up with that used by CHRGET. This section illustrates the various types ofvariable. If the character isn't a # then control is passed back to CHRGET. the BEEP subroutine is called. at the location pointed to by locations 45 and 46. Each variable occupies seven bytes ofmemory but these bytes are used differently by the different types of variable. To add a number of commands to BASIC would involve storing them in a table. . the CHRGET pointers are incremented to avoid reading the # twice and control is returned to the CHRGET routine. SIMPLE VARIABLES Simple variables are stored in memory starting immediately after the BASIC program. The diagram overleaf illustrates the arrangement ofmemory when a BASIC program is stored and the zero page locations which contain the start address of the various areas of memory. and preceding each with a #.BASIC and How it Works 225 The routine keeps its own pointer to the current byte of the BASIC pro gram in the READ subroutine.

44 Memory Allocation for a BASIC program Integer Variables The diagram shows how the seven bytes are used by an integer variable.Part 2 226 TOP OF BASIC RAM 55. VARIABLE NAME I 1st 2nd + 128 +128 VARIABLE VALUE High I Byte NULL Low I Byte I NULL 0 Format of an integer variable 0 NULL 0 .The Commodore 64 Omnibus .46 --------------BASIC PROGRAM STORAGE STARTOF BASIC 43. 52 END OF ARRA YS 49. 56 STRINGS BOTTOM OF STRINGS 51.50 ARRAYS _______________1 VARIABLES 1 START OFARRAYS 47.48 START OF VARIABLES 45.

and as the characters comprising the string. The first bit of the first byte of the mantissa is a sign bit. Floating Point Variables These are stored as an exponent and a mantissa. so the number is stored in the form mantissa * 2+ exponent. pointed to by the entry in the variable table.BASIC and How it Works 227 Note that three bytes are unused. The mantissa of a floating point variable is stored in packed Binary Coded Decimal form which gives 8 bit precision with the four bytes allocated. VARIABLE NAME 1st 2nd VARIABLE VALUE Expone- Mantiss- Mantiss- Mantiss- Mantiss- -nt -a -a -a -a Format of a floating point variable String Variables Astring variable is stored in two parts: as an entry in the variable table as illustrated in the diagram below. VARIABLE NAME 1st POINTER TO CHARACTERS 2nd Noof Low High + 128 Chars Byte Byte NULL 0 NULL 0 Format of astring variable Because the number of characters in the string is contained in one byte in the variable table entry . and so the use of integer variables doesn't result in a memory saving over floating point variables. which are stored in aseparate area of memory.

sinee eaeh variable oeeupies 7 bytes and the program ereated 4 variables.Part 2 228 the maximum number of eharacters in astring is 255. However when the variables have been ereated by the program there is a differenee of 28 bytes between the two .The Commodore 64 Omnibus . the start ofvariables and the start of arrays are at the same loeation. 10 20 30 40 50 60 70 PRINT "START OF VARIABLES BEFORE="i:PRINT PEEK(45)+256* PEEK(46) PRINT "START OF ARRAYS BEFORE="i:PRINT PEEK(47)+256* PEEK(48) A% = 100 B = 1000 C$ = "CBM-64" 0$ = C$+C$ piUNT"START OF ARRAYS AFTER="i:PRINT PEEK(47)+256* PEEK(48) Ifyou run the program you will see that before the variables are ereated. String variables mayaIso be defined in a program by sueh statements as: A$="HOW LONG IS A PIECE OF STRING" In this ease the entry for A$ in the variable table would point to a loeation within the BASIC program text. Type in the following program exaetly as i tappears to see the various variable types and their storage meehanisms. Type in the following eommand to examine the variable area: .

PEEK(Z): NEXT Z You should get a display like this: 2265 2266 2267 2268 2269 2270 2271 193 128 0 100 0 0 0 A (65 + 128) 1st char ofname Blank 2nd character of name High byte ofinteger variable Low byte of in teger variable Null Null Null 2272 2273 2274 2275 2276 2277 2278 66 0 138 122 0 0 0 B (66) 1st char ofname Blank 2nd char of name 128 + exponent 1st byte ofmantissa 2nd byte ofmantissa 3rd byte of man tissa 4th byte ofmantissa 2279 2280 2281 2282 2283 2284 2285 67 128 6 142 8 0 0 C (67) first character ofname Blank 2nd character of name N umber of characters Low & high bytes ofpointer to pro gram area Null Null 2286 2287 2288 2289 2290 2291 2292 68 128 12 244 159 0 0 D( 68) first character of name Blank 2nd character of name N umber of characters Low & high bytes ofpointer to string variable area Null Null From the comments added to the list you should be able to see that the arrangement of data in the variable area corresponds to that decribed above.BASIC and How it Works 229 FOR Z=2265 TO 2292 :PRINTZ. .

"%":GOTO 10070 10050 IF Z4<127 AND Z5<127 THEN PRINT CHR$(Z4)CHR$(Z5):GOTO 10070 10060 PRINT CHR$(Z4)CHR$(Z5-128). integer or string) is indicated by the way in which the array name is stored ."$" 10070 NEXT To use the program simply append it to your own program and type in direct mode GOTO 10000 when you need a variable dump. 1 10000 10010 10020 10030 10040 REM VARIABLE DUMP ZI=PEEK(45)+256*PEEK(46) Z2=PEEK(47)+256*PEEK(48)-21 FOR Z3=ZI TO Z2 STEP 7 Z4=PEEK(Z3):Z5=PEEK(Z3+1) IF Z4>127 AND Z5>127 THEN PRINT CHR$(Z4-128)CHR$(Z5128). Such a routine can be a valuable aid when developing programs. and could be made more useful by getting it to give the values assigned to each variable at the time of the dump. Arrays are stored immediately above simple variables. The array type (floating point. The following program will print a list of all variables used in a program.Part 2 230 One ofthe uses to which we can put this knowledge_ is in a short routine to dump the names of all the variables used in a program. Array Variables All three types of variable may be stored in array form. in which case different methods are used for allocating memory. starting from the address pointed to by locations 47 and 48. and could then be called with a SYS whenever required during the debugging stage of your BASIC program. For optimum efficiency it should be written in machine exactly .The Commodore 64 Omnibus .

The fifth byte contains the number of dimensions in the array. the header is larger by two bytes per additional dimension and these two bytes contain the size of the extra dimension. high byte order. ARRAY HEADER Element Element Element Element Element 0 1 2 3 4 Format of an array NOTE: Elements are stored in reverse order in string arrays. For arrays with more than one dimension.of Size of Nth Size of N-1th Byte Byte DIMensions DIMension DIMension Format of an array header Bytes one and two contain the array name and bytes three and four store the amount of memory occupied by the array in low byte. If no DIM statement exists then the default number is 10.231 BASIC and How it Works the same way as with simple variables. The Array Reader The header format is the same regardless of the array type. and occupies seven bytes plus an extra two bytes for each dimension beyond 1. The arrangement of an array in memory is illustrated below. In a one dimensional array bytes six and seven contain the size ofthe array as specified in the DIM statement that created it. The dimension bytes are stored in reverse order in . ARRAY NAME CHARACTERS 1st 2nd TOTAL BYTES Lo"w High No.

20) FOR Z=2067 TO 2085:PRlNT Z.PEEK(Z): NEXT Z You should get a list like this: 2067 2068 2069 2070 2071 2072 90 o 140 1 112 o These seven bytes are the loop counter.Part 2 232 the header to that in which they appear in the DIM statement that created them. Z. .The Commodore 64 Omnibus .of High Low Chars. 10 DlM AB(10. Byte Byte STRING Pointer Format of array elements Floating point array elements occupy 5 bytes. used to display the list. string elements occupy 3 bytes and integer array elements need only two bytes The next program creates an array and the immediate mode commands following it display the area ofmemory in which it is stored. Array Elements The way in which array elements are arranged in memory is illustrated in the following diagram: FLOATING POINT Expone- Mantiss- Mantiss- Mantiss- Mantiss- -nt -a 1 -a 2 -a 3 -a 4 INTEGER High Low Byte Byte NO.

high and low bytes. 0*256 + 21 = 21 2081 2082 0 11 Size of the first dimension. 0*256 + 11 = 11 2083 2084 2085 0 0 0 This is the start of the area of memory in which the array elements are stored .BASIC and How it Works 233 2073 0 2074 2075 65 66 A The array name B 2076 2077 140 4 The number ofbytes used. 4*256 + 140 = 1164 2078 2 The n umber of dimensions 2079 2080 0 21 Size of second dimension. high and low bytes. low and high.

When computers were first developed all programs for them were written in machine code. provide the screen editing facility and handle the cassette. for the 64? The reason is that machine language instructions are less powerful than BASIC instructions. Each type of processor has its own instruction set . but it was soon realised that this made programming very tedious.CHAPTER 18 MACHINE CODe ON THE 64 Although the 64 runs pro grams in BASIC.the 6510 is a variant of the weIl known 6502 processor and shares the same instructions. When you switch on the 64 it automaticaIly begins running a very sophisticated set of programs which are wri tten in the machine language of the 6510. "High-level" languages such as BASIC were developed to make programming easier by aIlowing the programmer to concentrate on the . BASIC. If the processor can interpret machine language pro grams directly. disk drive and printer. why go to the trouble of providing a second language. It is these pro grams which interpret the BASIC commands. The machine language of a microprocessor is a set of instructions which can be interpreted directly by the electronics within the microchip. as it may take several machine code instructions to perform the equi valent of one BASIC command. and programs are therefore less easy to write. this is not the (natural' language of the microprocessor (a 6510) at the he art of the computer.

The 6510 has three 8-bit data registers.addition. and three control registers. These flags are: .Machine Code on the 64 235 problem to be solved without getting bogged down in the details ofwritingthe code. the processor status register. Processor Status Register P This is not so much a register as a collection of single bits which act as <flags' to indicate various conditions ofthe processor. The accumulator is used in all calculations . and the X and Y index registers. They also playa useful role as loop counters and temporary storage registers. and are used to hold the data being processed by the 6510. subtraction and logical operations. THE 6510 MICROPROCESSOR The electronics of a microprocessor are extremely complicated. but from the machine code programmer's point of view the 6510 is a fairly simple device. X and Y Index Registers The index registers are so called because they may be used in a variety of ways to index tables of data in the memory. Almost all the data processed by the computer passes through this register. Accumulator This is the most used of all the registers. the stack pointer and the program counter (which unlike the others is a 16-bit register). These registers are similar to storage locations in memory but are built into the microprocessor chip. the accumulator.

.. D Sets Decimal mode. Pro gram Counter PC This 16-bit register stores the address in memory of the next instruction to be executed. THEN . The 6510 has a number of instructions which test the states of these flags and cause the pro gram to branch if a flag is in a certain state. Z The Zero flag. V Indicates an overflow or underflow in signed ari thmetic. Used in addition and subtraction operations. which is an 8-bit register thus: BIT 7 BITO B 0 z c Bi t 5 is not used. Indicates that the result ofthe last operation was zero. N Indicates a negative result.. These seven flags form the processor status register. GOTO of BASIC. These instructions correspond loosely to the IF .The Commodore 64 Omnibus .. I Interrupt disable. and play an important part in all machine code pro grams. B Break instruction just performed. .Part 2 236 C The Carry flag.

for performing arithmetic and logical operations on the contents ofthe accumulator. 169 1 means 'load the accumulator register with the number 1'. Instructions are usually expressed in hexadecimal as this is more convenient. For example. but may be followed by one or two further bytes as an operand. All 6510 instructions take the form of single byte numbers. This is a special program which allows you to enter and amend a sequence of machine code instructions using mnemonics to represent the instructions. The instruction given above would look like this in hexadecimal: $A9 $01 The $ prefix indicates that the numbers are in hex. and for testing the results of these operations. THE 6510 INSTRUCTION SET The instructions in the machine code instruction set include commands for moving data between the 64's memory and the three data registers. The simplest method is to POKE the numbers into store using a BASIC program.Machine Code on the 64 237 Stack Pointer S This is an eight bit register used to index the memory area in which subroutine return addresses are stored. and then translates these into the numbers which the . For more complex pro grams an assembler should be used. This method is unbelievably tedious and error-prone for all but the shortest of programs. Instructions may be entered in a number of ways.

Part 2 238 microprocessor can read. For example: LDA $0401 STA $0402 copies data from location $0401 (which in decimal is 1025) into the accumulator and then stores it in location $0402 (1026). For example. The # is used to distinguish a number from an address in assembly language. the instruction above could be entered in the form: LDA #$01 where LDA means LoaD the Accumulator. which differ in the way the memory is used. STA Copies the accumulator to memory. LDA This instruction copies a byte of data from memory into the accumulator. . There are a number of different forms of the LDA and ST A instructions. while the $ symbol again indicates a hexadecimal number. and #$01 is the number to be loaded.The Commodore 64 Omnibus . Transferring Data The first group of instructions move data between the 6510 registers and the memory. These different forms are called addressing modes. The instructions ofthe 6510 are described below.

so the full instruetion would be: . but from the loeation after the program instruetion. so the instruetion is eoded as: AD 01 04 (The low byte ofthe address is always given first.Machine Code on the 64 239 Absolute Addressing Mode Instruetions using this addressing mode give the address of the memory loeation as a two byte number following the instruetion code. ealled the operand. so the instruction is: 80 02 04 Immediate Addressing Mode In this mode the data is read not from a specified memory loeation.) Similarly: STA $0402 STA has the code $8D. For example: LOA $0401 The code for the LDA instruetion is $AD (or 173). This is used to load the aeeumulator with known values. The code for the instruetion in $A9. The # symbol is used to signify that the number following the instruction. is to be interpreted asanumber: LOA #1 means load the aecumulator with the number 1.

The code is $A5. $0000 to $OOFF. Other data transfer instructions. LDX. for which the high byte ofthe address is $00). and takes less storage space.i t would be meaningless! Zero Page Addressing Mode Here the memory location indicated is in page zero ofthe memory (the first 256 bytes. Because zero-page addressing is faster it is useful to store frequently used data in page zero. LDY. LOA $70 loads data from $007D.Part 2 A9 01 There is no corresponding ST A instruction . so the full instruction is: A5 70 This is equivalent to the absolute addressed: LOA $0070 AO 70 00 but is faster in operation. STX and STY transfer data to and from the X and Y index registers. These instructions have the following codes: MODE LDX LDY STX STY ABSOLUTE AE AC 8E 8C IMMEDIATE A2 AO - - ZERO PAGE A6 A4 86 84 .240 The Commodore 64 Omnibus .

wi th the carry operating in the same way as when you add two numbers with pencil and paper. The use of the carry flag allows n umbers of two bytes or more to be added together. If the result is greater then 255. 1 is added to the result. These are single byte instructions with no operands: CODe FUNCTION TAX AA Copies Accumulator to X register TAY A8 CopiesA to Y TXA 8A CopiesX toA TYA 9A Copies YtoA Arithmetic The 6510 can perform addition and subtraction operations. To add two single byte numbers stored in. Multiply and divide must be calculated by program. $1000 and $1001: CLC Clear the carry flag. otherwise it is cleared. . storing the result in the accumulator. LDA $1000 Load first number. Addition is performed by the command ADe. This adds a number in memory to the number in the accumulator. the least significant eight bits remain in the accumulator and the carry flag is set. say.Machine Code on the 64 241 Further instructions move data between the accumulator and the X and Y registers. as instructions are not provided. If the carry flag in the processor status register was set before the operation.

Suppose there are two 3 byte numbers stored in locations $A1. as the flag may have been set by a previous operation. $A2. STA $1002 Store result. and the sum of these is to be stored in $B1. $A6. $A3 and $A4. The code for CLC is $18. Like LDA and STA. This should always be done be fore an addition. The result is stored in $1002.Part 2 242 ADC $1001 Add second number. $A5. $B2. The method is as follows: CLC LDA ADC STA LDA ADC STA LDA ADC STA $A1 $A4 $Bl $A2 $A5 $B2 $A3 $A6 $B3 Clear carry flag Load lowest byte offirstnumber Add lowest byte ofsecond number Store lowest byte of sum Load second byte of first n umber Add second byte ofsecond number Store second byte of sum Load highest byte offirst number Add highest byte of second number Store highest byte of sum . N otice that the carry flag was cleared before the addition.The Commodore 64 Omnibus . ADC can be used in several addressing modes: Absolute Mode ADC<address> 6D Immediate ADC# <number> 69 Zero Page ADC < zero page address> 65 Larger numbers can be added in a similar way to that shown in the example above. The two original numbers are unaffected by the operation. and this would give the wrong result for the addition. $B3.

If the flag is clear before subtraction. Subtraction ADC is complemented by a subtraction command SBC. $0402: SEC LDA SBC STA LDA SBC STA $0401 #1 $0401 $0402 #0 $0402 Set carry = clear borrow Load low byte Subtract 1 Store new low byte Load high byte SubtractO Store result The last 3 instructions are not as pointless as they may seem. and will be cleared to indicate a cborrow' when the result of the subtraction is less than zero. This is used in a similar fashion to the ADC command.the carry flag must be set before the subtraction. The last three instructions load the high byte of the original number and subtract . subtracting 1 gives 255 ($FF) and clears the carry flag (sets cborrow'). The different addressing modes are again available: Absolute SBC < address > ED Immediate SBC# <number> E9 Zero Page SBC < zero page address> E5 This example subtracts 1 from a two byte number stored in $0401. If the low byte was zero to start wi th. which subtracts a number from that in the accumulator. There is an important difference . 1 is subtracted from the result. and again the carry flag is used when handling large numbers.Machine Code on the 64 243 Just as in normal arithmetic. the lowest parts of the numbers (the least significant bytes) are added first.

if locations $0401 and$0402 had originally contained the number $2900. but if the carry flag has been cleared.244 The Commodore 64 Omnibus . The Z flag will be set if the result of anyof these . There are no corresponding commands for numbers held in the X and Y registers. None of these increment and decrement instructions has any effect on the carry flag. So. Incrementing and Decrementing You can add or subtract 1 to a number in memory or in the X or Y register using Increment and Decrement instructions: FUNCTION CODE INX E8 Adds 1 to X register DEX CA Subtracts 1 from X register INY C8 Adds 1 to Y DEY 88 Subtracts 1 from Y These are single byte instructions with no operand. INC <address> Adds 1 to the contents of that address DEC <address> Subtracts 1 from the con ten ts of the address INC and DEC do not alter the accumulator or the .X and Y registers.uctions INC and DEC perform similar operations on numbers in the memory.Part 2 0. Addition and subtraction can be performed only on numbers in the accumulator. 1 will be subtracted from the result. the result would be $28FF. The two instr.

For example. The instructions have single byte operands which give the branch destination relative to the current program position. A vital point to remember is that the jump is not measured from the address of the branch instruction but from that of the next instruction. if the operand is between 128 and 255 the jump is backwards. So. that is if the result of the last operation performed was zero.) Branches The 6510 has a number of conditional branch instructions which test a flag in the P register and cause the program to branch ifthe tested flag is set or clear. . BNE 20 causes a jump forward of 20 bytes if the zero flag is set and: BNE 230 causes ajump back of26 bytes. and the size of the jump gets less as the number increases to 255. This is because the pro gram counter is increased to point to the next instruction before the branch instruction is processed. the instruction BEQ causes a branch if the Z flag is set. An operand of 128 causes a jump to the instruction whose address is 128 less than the current position in the program. after a non-zero result. If the operand is between 0 and 127 the jump is forwards. BNE does the opposite: the program branches if Z is clear. and the N flag will be set if Bit 7 of the result is set.Machine Code on the 64 245 operations is zero. (Z and N are similarly affected by ADC and SBC.

the flags may change again before the test is performed. A2 OA CA DO FD AD CD AB · This loop is repeated 10 times.. Consider the following: ··· · · '10 · LDX ~DEX BNE 253 LDA $ABCD · · · etc. THEN . There could however be a number of instructions between the beginning ofthe loop and the DEX instruction. so the flags are constantly changing. The loop in the example is literally a waste of time. doing nothing more than delay the program slightly. The instructions also provide a convenient way of creating loops. GOTO. If there are any instructions between the one whose effect you wish to test and the test i tself. Any instruction which modifies any of the 6510 data registers (and quite a few which don't) will modify the flags in the processor status register.The Commodore 64 Omnibus .. allowing programs to make decisions and act accordingly. An important point to remember is that the branch instruction must follow immediately after the instruction which creates the condition under test.. until the Z flag is set as the value in the X register becomes zero.. in . For example. a loop ending: DEX . at which point the program continues. as they are the machine code equivalents of BASIC commands like IF .Part 2 246 Branch instructions are indispensable in pro grams of any length.

Machine Code on the 64 247 LDA $1234 BNE • • • the flags will be set by the DEX instruction. in the memory location concerned. either in the accumulator. In signed arithmetic this bit indicates the . or if the INC or DEC instruction was used. It is also altered by addition and subtraction instructions. N and V. The N flag is a copy of Bit 7 of the register last altered. but immediately changed by the LDA instruction to indicate the nature of the number loaded into the accumulator. The Z or zero flag indicates a result of zero. and by the register shift instructions which are described later. The carry flag may be set or cleared by program. The fulllist ofbranch instructions is: CODE OPERATION =0 (Z set) BEQ FO Branch on result BNE 00 Branch on result< >0 BeS 90 Branch if carry set Bee BO Branch if carry clear BMI 30 Branch if negative (N set) BPL 10 Branch if positive (N clear) BVS 70 Branch if V set(overflow) BVe 50 Branch if V clear These instructions test the four flags Z. C. or the X or Y register.

248 The Commodore 64 Omnibus . All these instructions may test memory or numbers using the addressing modes described for LDA. These instructions do not alter either memory or the register. clear for positive. Z is set if A = Number. The flag may be cleared by the CL V instruction. Comparisons The three instructions CMP. C and N flags are altered to indicate the result ofthe comparison. The instructions CPX and CPY are similar. N is set if the operation (A-Number) would leave a 1 in Bit 7. except that the X or Y register is tested instead of the accumulator. CMP compares the accumulator with another number. but the Z. For example: CMP #1 compares the contents of the accumulator with the number 1.Part 2 sign of the number .set for negative. . The comparison leaves the flags in the state they would be in after setting the C flag and subtracting the number from the accumulator. The V flag indicates an overflow in twos complement arithmetic. otherwise Z is clear. That is: Cis set if A > = Number. CPX and CPY are used to compare registers with numbers in memory. otherwise C is clear.

The two bytes are the low and high bytes of the address of the data in memory. Instructions in this mode are written thus: LDA $C7 .Machine Code on the 64 249 MODE CMP CPX Cpy ABSOLUTE CD EC CC IMMEDIATE C9 EO CO ZERO PAGE C5 E4 C4 ADDRESSING MODES Many of the 6510 instructions can take several forms. Absolute Addressing This mode uses a two byte operand after the instruction code. Absolute addressing is indicated by the full address after the instruction: LDA $ABCD Zero Page Addressing This mode uses a one-byte operand following the instruction code. These and the other modes are explained below. These different forms of the instructions are said to use different addressing modes. zero page addressing and immediate addressing. providing different ways for specifying the memory location to be used by the instruction. This byte is the low part of an address in page zero ($0000 to $OOFF). We have already introduced three addressing modes: absolute addressing. because they address the memory in different ways.

but many instruetions use indexed forms ofindireet addressing. The high byte of the address is held in the next loeation. but holds the low byte of the address of another loeation where the data is to be plaeed. . For example: Absolute: LDA $ABCD loads the eontents of$ABCD Absolute Indexed: LDA $ABCD.X loads the eon ten ts of $ABCD+X.The Commodore 64 Omnibus . Indirect Addressing In the indireet addressing modes the indieated memory loeation is not used to store the data. so that the address of the data is Operand + X or Operand + Y. ean use simple indireet addressing. the jump instruetion JMP. The Y index register ean also be used in a similar manner. Only one 6510 instruction.Part 2 250 Indexed Addressing Indexed addressing uses the X or Y index register to modify the address given after the instrueton.X loads the aeeumulator with the eontents of $OOAB+X. As wen as absolute addressing there are also zero page indexed addressing modes. For example: LDA $AB.

So: Indirect Indexed: LDA (TABLE). as in CLC. Relative Addressing The address is given as an offset from the eurrent program address. Indexed indireet addressing uses the X register to index the zero page address in whieh the pointer is to be found. For example: . RTS ete. This is the addressing mode used by the relative braneh instruetions.X) Adds X to the address TABLE to find the zero page loeation where the data pointer is held. The eontents ofthe Y index register are added to the pointer to find the final address.Machine Code on the 64 251 Indirect Indexed & Indexed Indirect Addressing In indireet indexed addressing the single operand byte following the instruetion indieates the first of a pair of zero page loeations whose eontents form a pointer to the target loeation. Indexed Indireet: LDA (TABLE. OTH ER ADDRESSING MODES Implied addressing No address at all is specified.Y Reads the zero-page loeations TABLE and T ABLE + 1 and adds Y to the eontents to produee the address ofthe data.

and whose high byte is contained in location $ABCE. This causes the pro gram to jump to another location. There are two addressing modes: Absolute: JMP $ABCD The program continues at the location specified in the next two bytes. JSR $COOO Jumps to the subroutine at$COOO. JUMPS AND SUBROUTINES In addition to the relative branch instructions described above. A similar instruction.Part 2 BCS 35 means branch to the program instruction at the address 35 bytes above the current address in the program counter. Again no operand is used. is used to call subroutines. This addressing mode is used only by the register shift instructions. This may be used only in the absolute addressing mode. there is an absolute jump instruction. Accumulator Addressing The instruction acts only on the accumulator. for which the instruction code is $20. . JSR. JMP. Indirect: JMP ($ABCD) The program jumps to the address whose low byte is contained in location $ABCD.252 The Commodore 64 Omnibus . in this case $ABCD.

the pointer is set to $FF (the high byte is always $01 and can be disregarded). Data may be written to the stack by a pro gram. Data is removed in reverse order. the 6510 reads the first two bytes on the stack and resets the program counter to that address. so that it always indicates the first free location. and the stack pointer register is used to indicate the first free location in the stack. and the stack empties up to $OIFF. which 'pushes' the contents of the accumulator onto the stack. most ofthe time you can forget about the working of the stack and let i t look after i tself.Machine Code on the 64 253 Before jumping to the subroutine. The stack is designed to be used as a last-in first-out store. so that it may be restored on completion of the subroutine. and is incremented as data is removed by RTS commands. locations $0100 to $OIFF. This can be useful if you want to put a number on one side for a moment while performing another . which fills down from $OIFF. The command RTS causes the return from subroutine. the pointer would return to $IFF. Ifthe stack pointer should reach zero and a further subroutine call is made. and the oldest items in the stack would be overwritten. the 6510 stores the current value of the pro gram counter in a special area of memory called the stack. When the 6510 is reset. which would cause havoc! This is unlikely to happen except in very complicated programs. as subroutines are called the return addresses are added to the stack. and the pointer is decremented as the data is added by subroutine calls. using the instruction PHA. to which the next byte to be added will be written. The stack is held in page 1 of the 64's memory. This allows the nesting of subroutines.


The Commodore 64 Omnibus - Part 2

calculation. Numbers are pulled from the
the instruction PLA.



It is also possible to store the processor status
register P on the stack and recall it, using PHP














The stack pointer is automatically adjusted by the
6510 when these instructions are used. Don't
forget to take things off the stack in the reverse
order to that in which you put them on.
Be careful using these instructions. Remember
that they all use the same stack as is used to store
subroutine return addresses. This means that you
must be careful not to execute a RTS instruction
between writing data to the stack and reading it
back, or the pro gram will return to the wrong
place. You can of course call a subroutine after
writing the data; it will return without any
problem. What you must not do is return from a
subroutine which has pushed data onto the stack
before taking the data back offthe stack.
Two further instructions, TSX and TXS, allow you
. to modify the stack pointer.


Copies the stack pointer to the X

Machine Code on the 64




Copies the X register to the stack

This means you could, if you feIt confident,
maintain two or more stacks, but this is not
advisable. There would be a slight speed advantage
in using an area of page 1 as a table, indexed by the
stack pointer, but it would be both easier and less
hazardous to use indirect indexed addressing in
another part ofthe memory.

A microprocessor in a computer such as the 64 has
several jobs to do. As weIl as running the BASIC
interpreter program, the screen must be managed,
the keyboard checked for keypresses, and many
other routine operations performed. The ideal
microprocessor would be able to run many separate
programs at the same time, but such a processor
does not exist. Instead, the 6510 has a facility
which allows pro grams to be interrupted while
another program is run and then restarted at the
point at which they were stopped.
Two of the 40 pins on the 6510 chip are interrupt
request pins. Peripheral devices applying signals
to one or other of these pins will stop the 6510 in
the middle of whatever it is doing, and divert it to
another piece of program. The 6510 will be
returned to the original program by an instruction
at the end of the interrupt program. The two pins
are similar in use, the difference being that the
IRQ (interrupt re quest) pin is ignored if the I bit of
the processor status register has been set by an SEI
instruction, whereas the NMI (non-maskable
interrupt) pin can not be ignored.
When a suitable signal is applied to the IRQ pin the
6510 finishes the current instruction, stores the P
register and the program counter on the stack, sets


The Commodore 64 Omnibus - Part 2

the interrupt disable flag (I) in the P register and
jumps to the program at the address held in
locations $FFFE and $FFFF. The processor
continues to execute the program from this point
until a RTI instruction is reached. The RTI
(return from interrupt) acts in a similar way to
RTS, but restores the P register from the stack as
well as the program counter.
Interrupts in response to the NM! pin are similar,
except that the start address for the interrupt
pro gram is held in locations $FFFA and $FFFB.
The interrupt feature allows the effects of several
programs running at once. The 64 has a clock
circuit which interrupts the 6510 every 1/60 second
to call the keyboard scanning routine. This checks
the keyboard and puts the ASCII code of any key
held down into the keyboard buffer before RTIing.
The effect of this is that the rest of the BASIC
interpreting routines do not need any complex
subroutines to read the keys; they just look in the
keyboard buffer (this is wh at the BASIC GET
command does).
Interrupts are discussed further in Chapter 21,
which shows how interrupt programs may be used
to modify the display.

The two logical operations AND and 0 R, familiar
in BASIC, are also available in machine code, as is
a third, the Exclusive OR. The Exclusive OR
differs from OR in that 1 OR 1 gives 1, but 1 EOR 1
gives O. The mnemonics for the three instructions
are AND, ORA and EOR.
The truth tables for these operations are:

Machine Code on the 64



























The instruetions all aet on the aeeumulator.
Logical instruetions are useful for testing and
modifying seleeted bits within a byte without
altering the rest. For example the AND instruetion
may be used to mask apart of a byte. To inspeet the
first four bits of loeation $1234, the data would be
loaded into the aeeumulator and ANDed with the
number 15 (15 in binary is 00001111). As the AND
operation only sets the bits whieh are set in both
the numbers in the operation, the top four bits of
the result will be zero, and the lower four bits will
be a eopy of the lower four bits of loeation $1234.
The instruetion sequenee would be:
LDA $1234
AND #15

There are four shift instruetions available whieh
shift or rotate the bits in the aeeumulator or

Shifts the aeeumulator to the left. A
zero is plaeed in Bit 0 and Bit 7 is moved
to the earry flag. This is equivalent to
multiplying the aeeumulator by two.

The Commodore 64 Omnibus - Part 2






The ASL operation

Shifts the accumulator to the right. A
zero is placed in Bit 7, and Bit 0 it moved
to the carry flag. This is equivalent to
dividing the number in the accumulator





The LSR operation

Rotates the number in the accumulator
to the left. The carry flag is copied to Bi t
0, and Bit 7 is moved to the carry flag.



The ROL operation

Rotates the accumulator to the right.

Machine Code on the 64


The ROR operation
Machine code pro grams are called from BASIC by
the SYS command. This is similar in effect to the
GOSUB command except that the subroutine
called is a machine code routine at the address
specified in the SYS command. Control is returned
to BASIC when the routine is completed by the
machine code instruction RTS. The SYS command
is followed by the address of the start of the
machine code program. For example:
SYS 64738

calls the routine in ROM which resets the 64 when
it is switched on. Don't try this if you have a
valuable program loaded - it will be erased.
Storing Machine Code Pro grams
The most convenient place to store most machine
code pro grams is in the 4k block of memory
between 49152 ($COOO) and 52247 ($CFFF) which
is not used by the 64 in the execution of BASIC
If your pro gram is longer than 4k i t may be placed
lower down in memory in the area usually reserved
for BASIC programs. This area normally extends

The Commodore 64 Omnibus - Part 2


from 2048 to 40759 but you ean reserve apart of it
for maehine eode pro grams by altering the 'top of
memory' pointer in loeations 55 and 56.
To use this method, work out the new top of
memory you need by subtraeting the length ofyour
maehine code program from 40759, and POKE the
low byte of that address into loeation 55 and the
high byte into loeation 56. Finally reset the
pointers by typing:

The memory above the new 'top of memori is now
proteeted from being overwri tten by BASIC
The Kernal Routines
Many of the subroutines present in the 64's ROM
ean be used in your machine eode pro grams. Some
of the most aeeessible and weH doeumented form
part ofthe operating system eaHed the kernal.
To enable you to make use ofthese routines, a table
of their start addresses is kept in memory - a
feature shared by all Commodore maehines.
Calling eaeh routine involves a JSR to the
appropriate part of the table. By arranging the
table in this way, pro grams wri tten on one
Commodore machine may be more easily
translated to run on another. An example of the
use of the kernal routines to send output to a
printer may be found in Chapter 26, and a list of
the routines and their functions is given in
Appendix 1l.
Learning to Write Machine Code
This ehapter is not intended to teaeh you aH there
is to know about maehine code programming,

Machine Code on the 64


rather it introduces the fundamentals of the
language. If you wish to study the subject further,
there are a number of books aboout the 6502/6510
microprocessors which you may find helpful.
We have written a number of machine code
pro grams for this book, and if you study these you
will soon get a feel for the language, and realise
that despite first appearances, machine code
programming is not really very difficult.


As weIl as the normal text display, the 64 can
produce a high resolution bit-mapped display in
which the pixels correspond to individual bits in a
defined area ofmemory. There are two alternative
bit-mapped display modes: standard bit-mapped
mode, which has a screen resolution of 320 pixels
by 200 pixels in two colours; and multicolour bitmapped mode which has a lower resolution of 160
by 200 pixels, but in four colours.
The graphics modes are controlled by the VIC-TI
chip. Bit 5 ofthe control register at location 53265
selects bit-map mode: if the bit is set, bit-mapped
mode is selected; ifthe bit is clear the 64 display is
in text mode. To select multicolour bit-mapped
mode, Bit 4 of the second VIC control register at
location 53270 must also be set.
Display Memory
When you enable bit-mapped mode, you must also
decide where in memory the screen information
will be stored. Bit mapped displays need nearly 9k
of memory, 8000 bytes for the picture data and
1000 for the text screen memory, which in the bitmapped modes is used to hold colour information.
The VIC chip can only address 16k of memory at a
time, so the two blocks of memory needed for bi tmapped displays must He within one ofthe four 16k
banks or seetions which make up the 64k of total
memory space in the 64.
Within the 16k bank, the lk oftext screen memory
may be set to begin at any location whose address is

Bit-Mapped Graphics - Part 1


a multiple of 1024, but the Bk bit-map display
memory area must begin either at the beginning of
the bank, or at the mid point, Bk above the start.
These limitations mean that the bit-map screen
memory can not be put in the obvious place at the
top of the user RAM (from 32k to 40k), as there is
no more RAM in this bank into which the text
screen memory could be placed. The best place for
the bit-map display memory is therefore at the top
of the second bank, from 24576 to 32575, with the
text screen memory beginning at 23k (23552). This
leaves about 21k of memory free for BASIC
programs, which should be enough for most
The bank which the VIC chip addresses is set by
two POKE commands. First the lowest two bits of
the data direction register ofthe CIA interface chip
must be set to 1 by:
POKE 56578, PEEK(56578) OR 3

and the bank number must be POKEd to the
lowest two bits ofthe interface port at 56576:
POKE 56576, (PEEK(56576)AND252) OR B

where B is the bank number given by the table:




oto 16k






32k to 48k



48k to 64k


The Commodore 64 Omnibus . The position of the text screen within the bank is controlled by the four highest bits of location 53272. (PEEK(56576) AND 252) OR 2 POKE 53265.clearing Bit 5 in location 53265 and resetting the . If the bit is zero the bit-mapped display is placed at the beginning ofthe bank. Restoring the text display by program is a matter ofreturning all the registers to their normal values . which is 7. 120:REM SET MEMORY POINTERS Restoring the Text Display To restore the normal display manually. PEEK(56578) OR 3 POKE 56576. to set the 64 to the bit-mapped display mode with the display at 24k. we need the following short program: 5 10 20 30 40 REM SELECT BANK 16-32K POKE 56578. you can hold down RUN/STOP and tap RESTORE. The value to be POKEd into location 53272 is therefore 7*16 + 8. Bit 3 of 53272 must be set. the four most significant bytes must be set to 23-16.Part 2 264 Screen Memory Positioning The position within the 16k bank ofthe bit-mapped screen is controlled by Bit 3 of location 53272. To set the bit-map display to begin at 24k. So. To place the text screen memory at 23k. PEEK(53265) OR 32:REM SET BIT MAPPED MODE ON POKE 53272. The value ofthese bits is the number of 1k uni ts by which the start of the screen memory is offset from the beginning ofthe 16k bank. which is the mid-point of the 16k-32k bank. which is 120. Ifthe bit is 1 the screen memory begins at the mid-pointofthe bank.

the colour displayed for a bit set to 1 in display memory . 21 POKE 56578. PEEK(53265) AND 23 POKE 53272. PEEK(56576) OR 3 When run. you must clear the memory by POKEing it with zeros. Add the following lines to the previous pro gram: 100 200 210 220 230 GET K$: IF K$="" THEN 100 POKE 53265. For example. the pro gram will set up a highresolution display and wait until you press a key. The 'foreground' colour . Line 50 sets the colours. which is controlled by the four highest bits of the screen memory. Add the following two lines to the program. and line 60 clears the screen memory. These correspond to the data with which the memory happened to be filled when you set bit-mapped mode. to set a foreground colour of red (colour 2) and a white background (colour 1). Each number in this memory area controls the colour of an 8x8 block of pixels on the high resolution display. Colour The colour of a bit-mapped display is controlled by the numbers in the text screen memory. .Part 7 265 address pointers. To clear the screen. each location in the text memory must be set to 16*2 + 1. Clearing the Screen The display you see when you run the program will be filled with random blocks of colour.Bit-Mapped Graphics . while the background colour depends on the four lowest bits. after which the normal display will be restored. PEEK(56578) OR 3 POKE 56576.

Bit 4 of location 53270 must be set. MULTICOLOUR BIT-MAPPED MODE Multicolour bit-mapped mode is similar to standard bit-mapped mode. 0: NEXT The process of setting the colours and clearing the screen takes around 35 seconds . except that the screen resolution is reduced. by the command: POKE 53270. and that each pixel may take one of four colours.266 The Commodore 64 Omnibus .Part 2 50 60 FOR L=23552 TO 24551: POKE L. 33: NEXT L FOR M=24576 TO 32575: POKE M. A program to set the screen mode and clear the screen is described later. PEEK(53270) OR 16 .far from instantaneous! The only way of speeding up the screen clearing is to use a machine code program. The two extra colours are controlled by the colour memory (always located from 55296 to 56295) and the background colour stored in location 53281. Each pixel is controlled by two bits of data in the display memory as folIows: COLOUR BIT PATTERN COLOUR DISPLAYED 0 00 Background -Iocation 53281 1 01 Upper four bits of screen memory 2 10 Lower four bits of screen memory 3 11 Colour memory To change from standard bit-mapped mode to multicolour bit-mapped mode. but first a few words about multicolour bit-mapped mode.

Alternatively. 10 ********************* *** BIT-MAP MODES *** 20 ********************* 30 40 Starts at49152 50 * = $COOO 60 70 Colour 1 80 COLI = 686 Colour 2 (Background 90 COL2 = 687 100 COL3 = 688 110 MCBM 120 130 = 689 in Standard BMM) Colour 3 (MC BMM only) 1 = BMM. PEEK(53270) AND 239 USING MACHINE CODE WITH GRAPHICS Because of the speed problems using BASIC to control the graphics. machine code can be very useful. =MC BMM ° . you can type in the BASIC loader pro grams in Appendix 18 which you can use to load the machine code into your 64. Included in this book are a number of machine code programs to speed up graphics functions. These programs comprise aseries of DAT Astatements which form the machine code pro gram and a short routine to READ the DATA and POKE itintomemory. If you have an assembler and are familiar with machine code you can enter the machine code as it is given in this chapter and Chapter 20.Part 1 The multicolour bit must be cleared on returning to text mode by: POKE 53270.267 Bit-Mapped Graphics . and the first of these sets bit-mapped mode (BMM) or multicolour bit-mapped mode (MCBMM) and clears the bit-mapped screen.

pul COL3 into colour memory .268 The Commodore 64 Omnibus .Part 2 140 160 170 180 190 210 220 230 240 245 250 BMM LDA #1 STA MCBM BNE CLEAR Start for BMM MCBMM LDA #0 STA MCBM Start for MCBMM ! START BY CLEARING BMM SCREEN CLEAR LDA #$60 260 STA 252 270 LDA #0 280 STA 251 290 LDX #64 300 JSR WIPE 310 ! SET COLOURS 320 COLOUR LDA # 92 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 STA LDA STA LDA ASL ASL ASL ASL ORA LDX JSR 480 490 500 510 520 STA LDA STA LDX LDA 252 #0 251 COL1 A A A A COL2 #8 WIPE LDA MCBM BNE HIRES LDA #$D8 252 #0 251 #8 COL3 Wipe 64x256 bytes starting at $6000 Put COLi and COL2 into screen mem Multiply COLi by i6 AddCOL2 If MC.

Bit-Mapped Graphics .Part 1 530 540 545 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 710 720 730 740 750 760 770 780 790 795 800 269 JSR WIPE ! NOW SET POINTERS FOR BM MODE HIRES LDA ORA STA LDA AND ORA STA LDA ORA STA LDA STA 56578 #3 56578 56576 #252 #2 56576 53265 #32 53265 #120 53272 LDA BNE LDA ORA STA MCBM BMMEND 53270 [{MC. setMC mode #16 53270 Set bank 2 SetBMMon Set screen position BMMEND RTS ! SWITCH TO TEXT MODE ! LORES LDA 56578 Reset alt pointers tor text 810 ORA #3 Restore Bank 3 820 830 840 850 860 870 880 890 900 STA LDA AND ORA STA LDA AND STA LDA 56578 56576 #252 #3 56576 53265 #223 53265 53270 Clear BMM bit Clear MC bit .

Part 2 270 910 920 930 940 950 955 960 AND STA LDA STA RTS #239 53270 #21 53272 Reset pointers WIPE OVER BLOCK WITH CHARACTER IN ACCUMULATOR 965 970 WIPE 980 990 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 1130 LDY #127 Subroutine to fiU memorywith character in accumulator F1 STA (251).Y DEY BPL F1 PHA CLC LDA 251 ADC #128 STA 251 LDA #0 ADC 252 STA 252 PLA DEX BNE WIPE RTS END The exclamation marks in the listing are used by this assembler to indicate comments. and call the routine with the command: SYS 49152 . To use the machine code routine to set bit-mapped mode. and do not form part of the program.The Commodore 64 Omnibus . POKE the foreground colour into location 686 and the background colour into location 687.

use: SYS 49266 To set multieolour bit-mapped mode. at 24k. The bit-mapped sereen ean be proteeted from BASIC by resetting the top of BASIC memory thus: POKE 55. to clear the sereen. or to reset the eolours.0: POKE 56.Bit-Mapped Graphics . The fulllist of entry points is: BMM 49152 Clear. set BMM and eolours MCBMM 49159 Clear. there is a risk that the display may be eorrupted by the BASIC or by pro gram variables. and start the routine at line 210 ofthe listing using the eommand: SYS 49159 Other eall addresses allow you to swi teh from text to bit-mapped mode without clearing the sereen. 92: CLR . set MCBMM and eolours CLEAR Clear BM sereen and reset eolours 49164 COLOUR 49177 Seteolours IDRES 49221 Set to BM or MCBMM LORES 49266 Return to text mode NOTE: Beeause these routines plaee the bitmapped sereen in the middle of the BASIC program area.Part 1 271 To return to text mode. store the number of the third eolour in Ioeation 688.

The top line (Row 0) of the display is mapped onto the display memory like this: o 1 2 8 9 10 16 17 18 24 25 26 312 313 314 .272 The Commodore 64 Omnibus . PLOTTING POINTS The bit-mapped screen is arranged as a grid of 200 rows of 320 pixels (or 160 pixels in multicolour mode). A line such as this should be the first in every program which uses bit-mapped graphics. the layout of the memory is a little complicated.Part 2 Which sets the top of memory to 23732 and thus prevents any BASIC programs or variables overwriting the colour memory. Each byte in the screen memory represents a row of 8 pixels. 320 PIXELS HORIZONTALLY V E R T I C A L L Y However.

ROW CHAR LINE BYTE BIT = INT(Y/8) = INT(X/8) = Y AND 7 = ROW*320 + CHAR*8 + LINE + BASE = 7-(X AND 7) The pixel is set by: POKE BYTE.Part 1 273 315 316 317 318 319 3 4 5 6 7 The bytes are laid out in blocks of eight.Bit-Mapped Graphics . PEEK(BYTE) OR 2tBIT and cleared by: POKE BYTE. PEEK(BYTE)AND(255-2tBIT) The second program in our machine code graphics package plots points on the bit-mapped screen. corresponding to the characters of a text display. This layout means that plotting points on the bitmapped screen requires some calculation to convert X and Y co-ordinates to byte addresses. The following formulae can be used to set and clear pixels (the value BASE represents the address of the start ofthe bit-mapped screen memory). 10 20 30 ************ *** PLOT *** ************ 40 50 60 * = $COB8 80 90 100 BYTELO = 251 Starts at 49366 .

274 The Commodore 64 Omnibus .Part 2 110 120 130 140 150 160 170 180 190 200 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 BYTEHI Tl T2 XLO XHI Y COLNO MCBM BASE PLOT = = = = = = = = = 252 253 254 679 680 681 685 689 24576 = YI8 LDA LSR LSR LSR STA Y A A A ROW Find ROW LDA LSR LDA ROR LSR LDX XHI A XLO A A MCBM FindCHAR 370 380 BEQ PLOT1 LSR A 390 PLOT1 400 410 420 430 440 450 460 470 480 490 500 PI STA CHAR I{not MC mode CHAR =X18 LINE = YAND7 ROW ROW Tl #0 T2 #6 TIMES2 = ROW*64 LDA Y AND #7 STA LINE LDA STA LDA STA LDX JSR I{ MC mode then CHAR =X14 .

Bit-Mapped Graphics .Part 1 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 DEX BNE LDA STA LDA STA JSR JSR CLC LDA ADC STA LDA ADC STA 275 PI T2 BYTEHI Tl BYTELO TIMES2 AddROW* 256 TIMES2 Tl BYTELO BYTELO T2 BYTEHI BYTEHI BYTE now holds ROW*320 670 680 690 700 710 720 730 740 750 760 LDA STA LDA STA JSR JSR JSR CLC LDA Tl 770 780 790 800 810 ADC STA LDA ADC STA BYTELO BYTELO T2 BYTEHI BYTEHI BYTE now holds FindCHAR*8 #0 T2 CHAR Tl TIMES2 TIMES2 TIMES2 Add CHAR*8 to BYTE ROW*320 820 830 840 850 860 870 880 CLC LDA ADC STA LDA ADC + CHAR*8 Add LINE to BYTE LINE BYTELO BYTELO #0 BYTEHI .

Part 2 276 890 STA BYTEHI BYTE holds ROW*320 +LINE 900 910 920 930 940 950 960 970 975 980 ! BYTE CHAR*8 985 990 + CHAR*8 CLC Add screen start address LDA #<BASE Low byte ofBASE ADC STA LDA ADC STA BYTELO BYTELO #>BASE High byte ofBASE BYTEHI BYTEHI BASE + ROW*320 + + LINE = LDA MCBM BEQ MCPLOT 1000 1010 1020 1040 1050 BMPLOT LDA XLO 1060 AND #7 1070 STA BITT SEC 1080 LDA #7 1090 1100 SBC BITT 1110 STA BITT 1120 CLC 1130 1140 1150 1160 1170 P2 1180 1190 LDA LDX BEQ ASL DEX BNE 1200 1210 P3 LDY #0 Branch if MC mode selected Normal mode PLOT BITT = X AND 7 BITT=7-(X AND 7) IfBITT < > 0 then {ind2tBITT #1 BITT P3 A P2 Accumulator now holds 2 tB ITT .The Commodore 64 Omnibus .

Y 1260 STA (BYTELO).y 1340 RTS Standard mode plot ends here 1350 1360 1380 1390 MCPLOT LDA XLO 1400 AND #3 1410 STA BITT 1420 SEC 1430 LDA #3 1440 SBC BITT 1450 ASL A 1460 STA BITT Plot in MC mode BITT=2*(3-(X AND 3) 1470 1480 1490 1500 1510 1515 1520 MCPl 1530 1540 1550 MCP2 LDY LDA AND LDX BEQ ASL DEX BNE STA 1560 1570 LDA #%11111100 1580 1585 LDX BITT BEQ MCP4 #0 COLNO #3 BITT MCP2 A MCP1 COLS Moue colour number to correct position in byte COLS = COLNO * 2tBITT Setup mask tor pixel .y Plot the pixel 1270 1280 RTS 1290 1310 UNPLOT EOR #$FF Clear the pixel 1320 AND (BYTELO).Bit-Mapped Graphics .Y 1330 STA (BYTELO).Part 1 277 1220 1230 LDX COLNO Test tor Plotor Unplot 1240 BEQ UNPLOT Branch i{COLNO=O 1250 ORA (BYTELO) .

Y 1650 ORA COLS 1660 1665 1670 1680 1690 1700 1710 1720 1730 1740 1750 1760 1770 1780 1790 1800 1810 1820 1830 1840 1850 1860 1870 STA (BYTELO). X AND 255 . the high byte into Ioeation 680.Part 2 278 1590 1600 MCP3 SEC ROL A 1610 1620 1630 1640 MCP4 DEX BNE MCP3 AND (BYTELO). and Y into Ioeation 681 (these Ioeations are Iabelled XLO. XHI and Y in the program above) using the eommands: POKE 679.The Commodore 64 Omnibus .T2) BY 2 TIMES2 LDA ASL ASL ADC STA RTS ROW CHAR LINE BITT COLS #0 T2 Tl T2 T2 NOP NOP NOP NOP NOP Called BITT because BIT isa 6510 instruction END To use the program. POKE the Iow byte of the X co-ordinate into Ioeation 679.Y RTS Rotate mask to fit reqd pixel Mask out bits ofpixel Set new pixel state Store the byte End of MC plot MULTIPLY (T1.

The PLOT routine begins at location 49336.Bit-Mapped Graphics . In standard two colour mode. as shown in the table on page 56.Part 1 279 POKE 680. but you should design your BASIC pro grams to avoid using incorrect values. PO KE 685 with 1 to plot in the foreground colour. In multicolour mode. . X/256 POKE 681. Y Note that the pro gram does not perform any checks to make sure that the co-ordinates are within the screen limits. Using overlarge values of X or Y is unlikely to have any ill effects other than spoiling the appearance of the display. or with zero to plot in the background colour (to erase a pixel). the colours are numbered from 0 to 3. Location 685 (called COLNO in the pro gram) is used to select the colour in which the pixel is plotted. and so may be run by the command: SYS 49336.

we can perform the following calculations: M = DY/DX = (Y2-Yl)/(X2-Xl) C = Yl . If you try plotting a few lines by this method you will find that the lines appear broken if Y2-Yl is greater than X2-X1. .Yl and X2. and introduce line drawing and block fill routines. reverse the algorithm to loop from Yl to Y2 and calculate the valuesofX.CHAPTER 20 BIT MAPPED GRAPHICS . If this is so.PART 2 In this chapter we look further at the uses and applications ofbit-mapped graphics. and Cis a constant. DRAWING LlNES Straight lines may be drawn using the equation: Y=M*X+C in which M represents the gradient ofthe line.M*Xl and then plot the line with: FOR X=Xl TO X2: Y=M*X+C: JSR (PLOT) with a suitable subroutine to plot the pixels. To find the equation ofthe straight li ne between the two points Xl.Y2.

Bit-Mapped Graphics .Part 2 281 The third program in the machine code graphics package dra ws lines in this mann er between two points on the screen: 100 ************ 110 *** DRAW *** 120 ************ 130 140 150 * = $C1C8 160 ! 170 190 200 DRAW LDA X2L 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 370 380 390 DRAW1 400 410 420 430 440 STA LDA STA LDA STA XTL X2H XTH Y YT LDA STA SEC LDA SBC BCS LDA EOR STA SEC LDA SBC STA #0 NEG Starts at 49608 Take copy of li ne end co-ordinates DY Y2 Y DRAW1 NEG #1 NEG = ABS(Y2-Y) IfY2 <Y then set NEG Y Y2 DY SEC LDA X2L SBC XL STA DXL DX = ABS (X2-X) .

Part 2 282 450 460 470 480 LDA SBC BCS LDA X2H XH DRAW2 NEG 490 500 510 520 530 540 550 560 570 DRAW2 580 590 600 610 620 EOR STA SEC LDA SBC STA LDA SBC STA #1 NEG BNE LDA BNE LDA DRAW2A DXL DRAW2A IfDX =0 then set #1 IfX2 <x then switch NEG XL X2L DXL XH X2H DXH NEG=I 630 STA NEG 640 650 DRAW2A LDA DY 660 670 680 690 700 DRAW2B IfDY=Othenset NEG=I BNE DRAW2B LDA #1 STA NEG LDA DXH Ir DX > =DY then SHALLOWelse STEEP 710 BNE SHALLOW 720 LDA DXL 730 CMP DY 740 BCS SHALLOW JMP STEEP 750 760 770 SHALLOW SEC Draw shallow lines with DYIDX < =I LDA X2L 780 Ir X2 <Xl then swap co-ordinates .The Commodore 64 Omnibus .

Part 2 790 800 810 820 830 835 840 SHAL1 SBC LDA SBC BCS JSR 850 860 870 880 890 900 910 920 930 940 950 960 970 980 990 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 DRAW3 1130 1140 1150 1160 1170 STA LDA STA LDA STA LDA STA JSR DIVLO #0 DIVHI DXL 01 DXH 02 DIVIDE LDA STA LDA STA JSR STA LDA STA LDX BEQ CLC LDA ADC STA LDA ADC STA JMP LDA SBC STA LDA SBC STA XL MXL XH MXH MULT C P4 CH NEG DRAW3 283 XL X2H XH SHAL1 SWAP LDA DY Find gradient M=DYIDX Calculate C First find X* M [fM +ve then branch C=M*X+Y C Y C CH #0 CH SHLOOP Y C=Y-(M*X) C C #0 CH CH .Bit-Mapped Graphics .

284 The Commodore 64 Omnibus .Part 2 1180 ! 1190 SHLOOP 1200 1210 1220 1230 1240 1250 1260 1270 LDA STA LDA STA JSR XH MXH XL MXL MULT LDX NEG BNE SHL1 CLC Loop from X to X2 FindM*X IfM +ue then Y = M*X+C 1280 1290 1300 1310 SHL1 ADC C STA Y JMP SHL2 SEC 1320 1330 1340 1350 SHL2 1355 1360 1370 1380 1390 1400 1410 1420 1425 1430 1440 1450 1460 1470 1480 1490 1500 1510 1520 STEEP LDA SBC STA JSR C P3 Y PLOT CLC LDA ADC STA LDA ADC STA XL #1 XL XH #0 XH SEC LDA SBC LDA SBC BCS JMP X2L XL X2H XH SHLOOP IfX2> =X then repeat TIDY Finish off 1530 If M -ue then Y = C M*X Plot the point Increment X See ifX=X2 SEC LDA Y2 Draw steep lines with DYIDX>l .

Part 2 1540 1550 1560 285 CMP Y BCS STEEP1 JSR SWAP IfY2 <Y then swap coordinates 1565 1570 STEEP1 LDA DXL Find gradient DX/DY 1580 STA DIVLO 1590 LDA DXH 1600 STA DIVHI 1610 LDA DY 1620 STA D1 1630 LDA #0 1640 STA D2 1650 JSR DIVIDE 1655 1660 LDA Y Find Y*M 1670 STA MXL 1680 LDA #0 1690 STA MXH 1700 JSR MULT 1710 STA C 1720 LDX NEG 1730 BEQ ST1 1740 CLC IfM -uethenC= M*Y +X 1750 1760 1770 1780 1790 1800 1810 ST1 ADC STA LDA ADC STA JMP LDA XL C #0 XH CH STLOOP XL If M + ue then C = X M*Y 1820 SBC 1830 STA 1840 LDA 1850 SBC 1860 STA 1865 1870 STLOOP LDA 1880 STA C C XH #0 CH Y MXL Loop from Y to Y2 .Bit-Mapped Graphics .

286 The Commodore 64 Omnibus .Part 2 1890 1900 1910 1920 1930 LDA STA JSR LDX BNE #0 MXH MULT NEG STL1 1940 1950 1960 1970 1980 1990 2000 2005 2010 STL1 2020 2030 2040 2050 2060 2070 2075 2080 STL2 2085 2090 2100 2110 2120 2130 2140 2150 2155 2156 2160 TIDY CLC ADC STA LDA ADC STA JMP C XL CH P4 XH STL2 SEC LDA SBC STA LDA SBC STA C P3 XL CH P4 XH 2170 2180 2190 2200 2210 2220 FindM*Y Ir slope -ve then branch X M*Y+C = X = C-M*Y JSR PLOT Plot pixel CLC LDA ADC STA CMP BCC BEQ Iry < LDA XTH STA LDA STA LDA STA RTS =Y2 then repeat Y #1 Y Y2 STLOOP STLOOP XH XTL XL YT Y Set X and Y to new line end coordinates .

Bit-Mapped Graphics .Part 2 287 2230 2235 2240 MULT LDA 01 Multiply number in MX by gradient in Q 1- 2250 STA M1 Copy gradient to M1M3 2260 2270 2280 2290 2300 LDA STA LDA STA LDA 02 M2 03 M3 #0 2310 2320 2330 2340 2350 2360 2365 2370 STA STA STA STA STA STA P1 P2 P3 P4 MX3 MX4 LDY #24 2375 2380 MULT1 2390 2400 2410 LSR ROR ROR BCC M3 M2 M1 MULT2 2420 2430 2440 2450 2460 2470 2480 2490 2500 2510 2520 2530 2540 CLC LDA ADC STA LDA ADC STA LDA ADC STA LDA ADC STA MXL P1 P1 MXH P2 P2 MX3 P3 P3 MX4 P4 P4 Q3 Initialise product P to zero Set Y to repeat 24 times Shirt M to the right Ir nothing in carry then branch AddMXtoP .

Part 2 2545 ! 2550 MULT2 2560 2570 2580 2585 2590 2600 2605 2610 ASL ROL ROL ROL MXL MXH MX3 MX4 DEY BNE MULTI Repeat i{Y <0 LDA P3 Store result in accumulator RTS 2620 2630 2635 2640 DIVIDE LDA #0 STA 03 2650 2660 2670 2680 2685 2690 2695 2700 2710 2720 2730 2740 2750 2760 2765 2770 DVDI M ultiply MX by 2 Diuides DIV by D First set result Q to zero STA 02 STA 01 STA DIV3 LDY #24 Set to repeat 24 times SEC SubtractD {rom high bytes o{ DIV LDA SBC STA LDA SBC STA DIVHI Dl DIVHI DIV3 D2 DIV3 PHP Saue P register tor later 2775 2780 ROL 01 Rotate Q: mult by 2 and add carry 2790 2800 2810 2820 ROL ROL ASL ROL 02 03 DIVLO DIVHI M ultiply Diu by 2 .288 The Commodore 64 Omnibus .

Y2) .Bit-Mapped Graphics .Y) with (X2.Part 2 2830 2835 2840 2850 2855 2860 2870 2880 2890 2900 2910 2920 2930 2935 2940 DVD2 ROL DIV3 PLP BCC DVD2 Reload P register I{DN-D was <0 then branch LDA DIVHI SubtractD {rom new valueo{DN SBC STA LDA SBC STA CLV BVC D1 DIVHI DIV3 D2 DIV3 DVD3 LDA DIVHI 2950 ADC 01 2960 STA DIVHI 2970 LDA DIV3 2980 ADC D2 2990 STA DIV3 2885 3000 DVD3 DEY 3010 BNE DVD1 3015 3020 ROL Q1 3030 ROL Q2 3040 ROL Q3 3050 RTS 3060 3070 3080 SWAP LDA X2L 3090 3100 3110 3120 3130 3140 289 LDY STA STY LDA LDY STA XL XL X2L X2H XH XH Jump on to DVD3 Add D to new value o{ DIV Repeat loop 24 times M ultiply result by 2 Swap (X.

Part 2 290 3150 3160 3170 3180 3190 3200 3210 3220 3225 3230 3240 3250 3260 3270 3280 3290 3300 3310 3320 3330 3340 3350 3360 3370 3380 3390 3400 3410 3420 3430 3440 3450 3460 3470 3480 3490 3500 3510 3520 3530 3540 STY LDA LDY STA STY RTS X2H Y2 Y Y Y2 Label definitions PLOT XL XH Y X2L X2H Y2 XTL XTH YT DXL DXH DY D1 D2 DIVLO DIVHI DIV3 MXL MXH MX3 MX4 C CH 01 02 03 MI M2 M3 PI P2 = $COB8 = 679 = 680 = 681 = 682 = 683 = 684 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP .The Commodore 64 Omnibus .

Y) to (X2. The number stored in DIV (DIVLO. and Y into 681.Part 2 3550 3560 3570 3580 P3 P4 NEG END 291 NOP NOP NOP To use the program to draw from (X.Bit-Mapped Graphics . finding Y for each value of X by the formula Y = M*X + C. The program begins at location 49608. and the result (the quotient) is stored in Q (QI to Q3). the line is drawn by the SHALLOW routine which scans from X to X2. Similarly POKE X2 into 682 and 683. The lower two bytes of the result . and so is run by: SYS 49608 Like the PLOT routine. the high byte of X into 680.Y2). The program works by first checking the gradient of the line. DIVHI and DIV3) is divided by the number in D (DI and D2). If the line is steep. Set the colour in which the line is to be drawn by POKEing a suitable number into 685. You will find that if a line runs off one side of the screen it will reappear at the other. The subroutine DIVIDE is used to calculate the gradient. and it is unlikely that any memory other than the display memory will be corrupted. POKE the low byte of X into 679. this program does not include any checks to ensure that the lines do not run off the screen. You should however include suitable checks in your BASIC programs to avoid spoiling the displays. the STEEP routine is used to draw the line by scanning from Y to Y2 and finding X by each point with the formula X=M*Y+C. If the line is shallow (the gradient is less than or equal to 1). in the same way as with the PLOT routine. The program works equaHy weH in ei ther screen mode. and Y2 into 684.

The MUL T subro utine multi plies the gradi ent stored in Q by the val ue of X or Y stored in MX (MXLO. Again the lower two bytes of the resul t are the fracti onal part.292 The Comm odore 64 Omnib us . MX3 and MX4) and stores the produ ct in P (PI to P4). to plot all the pixel s in a given rectan gle in one colour.Part 2 are the fracti onal part of the gradi ent: as the progr am is desig ned alway s to draw lines with a gradi ent less than 1 the fracti onal part is very impo rtant. Y SYS 49336 NEXT Y NEXT X 30 40 50 60 70 The mach ine code routin e is: 10 20 30 40 50 60 70 ************ *** FILL *** ************ * = $C4E2 Starts at 50402 . The routin e is very short. FILLING BLOCKS The fourth mach ine code progr am in the graph ics set is a FILL routin e. with the highe st bit in P4 ifthe produ ct repre sents the X coordin ate of a steep line. MXH I. the mach ine code equiv alent of a BASIC progr am such as: 10 20 FOR X = Xl TO X2 POKE 679. X AND 255: POKE 680. X/256 FOR Y = Y1 TO Y2 POKE 681. so the X or Y coord inate to be plotte d is found in P3.

Part 2 90 100 110 120 130 140 150 160 170 180 190 200 210 230 240 XL XH Y = 679 = 680 = 681 ! X2L X2H Y2 = 682 = 683 = 684 ! PLOT = $COB8 FILL LDA Y 250 260 280 FILLI 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 Saue Y to reset tor eachloop STA YT JSR CLC LDA ADC STA PLOT Plot point Y #1 Y lncrement Y LDA Y2 CMP Y BCS FILLI LDA STA CLC LDA ADC STA LDA ADC STA Repeatloop until Y>Y2 YT Y Reset Y XL #1 XL XH #0 XH IncrementX SEC LDA X2H SBC XH FindX2-X 293 .Bit-Mapped Graphics .

294 The Comm odore 64 Omnib us . Using the Grap hics Rout ines To finish off. In addit ion to the four graph ics routin es.a loade r progr am for this is also given in Appe ndix 18.Part 2 510 520 530 LDA X2L SBe XL Bes FILL1 540 550 560 ! 570 YT RTS Repea t loop if X<=X 2 NOP The FILL routin e uses the same locati ons as the Draw routin e. The co-or dinate s of the bottom righthand corne r of the block shoul d be PO KEd in to locati on 682. Before runni ng them you must load the graph ics mach ine code into the 64 . and the Y co-ordinate into locati on 681. 683 and 684.see Appe ndix 18 for detail s ofhow to do this. The graph ics routin es are split into four separ ate BASI C loade r progr ams which shoul d each be run in accordance wi th the instru ction s in Appe ndix 18. Locat ion 685 is again used to select the colour. the first progr am below requi res the mixed mode mach ine code descr ibed in Chap ter 21 to run . POK E the X co-or dinate of the top left-h and corne r of the block to be filled in to locati ons 679 and 680. here are some short pro gram s which show the use of all the mach ine code routin es we have introd uced in the last two chapt ers. Grap hics Dem onstr ation Prog ram The first pro gram show s the routin es in use and also uses the mixed mode displa y routin e descr ibed in Chap ter 21. 100 REM ********************* .

Bit-Mapped Graphics .Part 2 110 120 130 140 150 160 170 1000 1010 1020 1030 1040 1050 1060 1070 2000 2005 2010 2020 2030 2040 2050 2060 2090 2100 2500 2510 2520 2530 2540 3000 3010 3020 3030 3040 3050 295 REM *** GRAPHICS DEMO *** REM ********************* REM REM GRAPHICS PACKAGE MUST BE LOADED REM BEFORE THIS PROGRAM IS RUN REM REM REM SET MULTICOLOUR MODE POKE 53281.6:POKE 688.2 FOR Y1=10 TO 150 STEP 5 X2=Y1 .15:POKE 686.225:SYS 50468 PRINT"{CLS}{23 * CD}" PRINT" {RVS}MULTI COLOUR BIT MAPPED DISPLAY{ROF}" FOR T=l TO 1000: NEXT T REM PLOT POINTS PRINT"{CLS}{23 * CD}" PRINT" {RVS}PLOTTING POINTS " FOR A=O TO 2*n STEP 0.X POKE 681.1 X=100+50*SIN(A) Y=60-50*COS(A) GOSUB 2500 NEXT A FOR T = 1 TO 1000: NEXT T GOTO 3000 POKE 679.2:POKE 687.0 SYS 49159 REM SET SPLIT SCREEN POKE 50518.Y POKE 685.1 SYS 49336 RETURN REM DRAW LINES PRINT"{CLS}{23 * CD}" PRINT" {RVS}DRAWING LINES" X1=10:Y2=150: POKE 685.

05 X = 160+J*SIN(N) Y = 95+K*COS(N) POKE 679.X:POKE 681.X2:POKE 684.Y1:POKE 682.70: POKE681.2:POKE 687.1:POKE 686.7 SYS 49152:REM SET UP BMM J=0:K=80 FOR N=O TO 2*IT STEP .Y SYS 49336:REM PLOT IT! NEXT N J = J+10:K = K-10 IF K >-10 THEN 40 GET K$: IF K$="" THEN 120 SYS 49266:REM BACK TO TEXT .296 The Commodore 64 Omnibus .Part 2 3060 3070 3080 3090 4000 4010 4020 4030 4040 4050 4060 4070 POKE 679.Y2 SYS 49608 NEXT Y1 FOR T = 1 TO 1000: NEXT T REM FILL BLOCK PRINT"{CLS}{23 * CD}" PRINT" (RVS}FILLING BLOCKS" POKE 685. 10 20 30 35 40 50 60 70 80 90 100 110 120 130 REM PLOT PATTERN POKE 685.90 SYS 50402 FOR T = 1 TO 1000: NEXT:END The program will end with the computer in mixed display mode.30 POKE 682.X1:POKE 681. Plotting Points This program uses the PLOT routine to draw a pattern on the screen.1 POKE 679. Use RUN/STOP and RESTORE to return to normal text mode.130: POKE684.

4 5 6 10 15 20 30 40 45 50 H=180:W=140:XC=80:YC=100:S=10 POKEI020. (XC-W/2)AND 255:POKE 680.0:POKEI021. (PEEK(685) +1-(PEEK(685)=3»AND 3 NEXT FOR X=XC-W/2+S TO XC+W/2 STEP 5 60 70 80 90 115 POKE 679. XC/256:POKE 684.YC SYS 49608:POKE 685.Part 2 297 Headache! This program uses the DRAW routine to create a pattern on the multi-colour bit-mapped mode screen and demonstrates the effect of changing the colours using the COLOUR routine.YC+H/2 POKE 682.XC AND 255:POKE 683.X AND 255:POKE 680.6:POKE 53281. XC/256:POKE 684.XC AND 255:POKE 683.(XC-W/2)/256:POKE 681.(PEEK(685)+ 1-(PEEK(685)=3»AND 3 NEXT FOR Y=YC+H/2-S TO YC-H/2 STEP5 120 130 140 145 150 POKE 679.YC SYS 49608:POKE 685. X/256:POKE 681.XC AND 255:POKE 683.96 POKE685.Y POKE 682.1 POKE 686.(XC+W/2)/256:POKE 681.I:POKE 688.12: SYS 49159 FOR Y=YC-H/2 TO YC+H/2 STEP 5 POKE 679.Bit-Mapped Graphics .YC SYS 49608:POKE 685.2:POKE 687.Y POKE 682. (XC+W/2) AND 255:POKE 680. XC/256:POKE 684.(PEEK(685)+ 1-(PEEK(685)=3»AND 3 NEXT FOR X=XC+W/2-S TO XC-W/2 STEP5 .

A(N) AND 255: POKE 680.(PEEK(53281)+1) AND 15 SYS 49177 FOR T=l TO 200:NEXT:NEXT GET A$:lFA$="" THEN 200 SYS 49266 END Lace This program uses the DRAW routine to create a lace pattern on the standard bit-mapped screen.XC AND 255:POKE 683.(PEEK(687)+1) AND 15 POKE 688.3 : SYS 49152 L=120: J=80 FOR H=l TO 5 FOR N=l TO 36 K = N/18*n A(N)= 128+L*SlN(K): B(N)=88+J*COS(K) NEXT N FOR N=l TO 36 M = N+12 lF M>36 THEN M=M-36 POKE 679.(PEEK(685)+ 1-(PEEK(685)=3»AND 3 NEXT FOR CC=l TO 96 POKE 53280.(PEEK(686)+1) AND 15 POKE 687.6: POKE 687. 10 20 30 40 50 60 70 100 110 120 130 160 DlM A(36).The Commodore 64 Omnibus .YC-H/2 POKE 682.YC SYS 49608:POKE 685.(PEEK(53280)+1) AND 15 POKE 686. X/256:POKE 681. B(36) POKE 686.X AND 255:POKE 680.A(N)/256: POKE 681.B(N) . XC/256:POKE 684.Part 2 298 160 170 180 185 190 191 192 193 194 195 196 197 200 210 220 POKE 679.(PEEK(688)+1)AND 15 POKE 53281.

Part 2 170 180 190 200 210 500 510 299 POKE 682.5) FOR X=-XL+1 TO XL-1 Y=H*SIN(W*SQR(X*X+Z*Z» X2=XC+X+Z Y2=INT(199-(YC+Y+Z/2)+.1:SYS 49152 FOR Z=-ZR+1 TO ZR-1 STEP 5 XL=INT(XR*SQR(l-(Z*Z)/ (ZR*ZR»+.5) X=-XL Y=H*SIN(W*SQR(X*X+Z*Z» X1=X+XC+Z Y1=INT(199-(YC+Y+Z/2)+.5) IF Y2>=LB(X2-XA) THEN 680 LB(X2-XA)=Y2 IF UB(X2-XA)=0 THEN UB(X2-XA) = Y2 GOTO 700 IF Y2<=UB(X2-XA) THEN 730 .1 SYS 49608 NEXT N L=L/2: J=J/2 NEXT H GET K$: IF K$=""THEN 500 SYS 49266:ENO JR'sHat This program uses the DRAW routine to draw a three dimensional graph .043:XA=107 FOR S=l TO 424 UB(S)=0:LB(S)=1000 NEXT S POKE 686.B(M): POKE 685.A(M)/256: POKE684.A(M) ANO 255: POKE 683. 100 110 120 200 210 220 300 500 510 520 530 540 550 600 610 620 630 640 650 660 670 680 OlM UB(424). LB(424) XC=320:YC=115:XR=175:ZR= 120 H=40:W=0.Bit-Mapped Graphics .it takes quite a while to run.2: POKE 687.

1:SYS 49608 X1=X2 Y1=Y2 NEXT X NEXT Z GET K$:IF K$="" THEN 1000 SYS 49266 .The Commodore 64 Omnibus .Part 2 300 690 700 710 720 730 740 750 760 1000 1010 UB(X2-XA)=Y2 POKE 679.Y2 POKE 685.(X2/2) AND 255:POKE 683.(X2/2)/256:POKE 684.Y1 POKE 682.(X1/2)/256:POKE 681.(X1/2) AND 255:POKE 680.

The process must happen . but to understand fully you must know how the VIC-I1 chip generates its displays. This chapter deals wi th the techniques used in creating such displays. called raster scanning. This process. varying in intensity as it goes. Where this beam strikes the screen the phosphor glows. or more than eight sprites for example . This variation in intensity is dictated by information from the TV transmitter and produces a corresponding variation in the intensity with which the phosphor glows.CHAPTER 21 DISPLAY INTERRUPTS The VIC-II chip is a very powerful device and allows many different graphics displays to be created. To create a full picture the electron beam scans across the screen in rows. continues until the bottom of the screen is reached. and how a TV or monitor works. at which point it starts all over again at the top. It is possible to extend these capabilities to enable the creation of displays using several different character sets. TV Pictures The pictures on a TV screen are created by an electron beam which is directed at the phosphor coated inner surface of the can even have mixed text and graphics. When the electron beam reaches the edge of the screen i t is turned off and the process starts again from a position just below the last starting position.

. the screen is coated with three different types of phosphor which emit the colours red. as weIl as luminance information. a ninth bit is required and this is Bit 7 of the control register at location 53265. the raster register (location 53266). blue and green when struck by the electron beam. To create a colour picture. It has two functions depending on whether data is written to it or read from it. The different phosphors are distributed in tiny dots or blocks over the screen and the colour TV signal must contain information about which of these points the electron beam should strike.PEEK(53266): GOTO 10 Obviously this number is changing very rapidly and incidentally is a good source of random numbers. is concerned with the current raster position (position down the screen) of the scaning electron beam.The Commodore 64 Omnibus . The Raster Register One of the VIC-II registers. Ifyou read the raster register the number returned is the bottom eight bits of the current raster position. as shown in this program: 10 PRINT"{CLS}".Part 2 302 many times a second to create a picture that doesn't flicker. In generating its displays the VIC-II chip takes data from video memory and uses it to create a signal which controls the electron beam in the TV in much the same way as a transmitted TV signal does. Since the raster position can be greater than 255.

Ifwe change the contents of788 and 789 (the Interrupt Re Quest vectors) to point to a routine of our own. The Interrupt Enable Register If Bit 0 of this register is set when araster interrupt is indicated in the interrupt status register. and so create the effects mentioned at the beginning of the chapter.the interrupt enable register. and when the two are equal this fact is indicated in the interrupt register. an interrupt will be generated and the 6510 will begin to execute a machine code program whose start address is stored in locations $FFFE and $FFFF (65534 and 65535). If you don't have an assembler. it is stored within the VIC chip and used in araster compare operation .Display Interrupts 303 If data is written to the raster register.the current raster position is compared with the stored value. Before returning to whatever program was being executed at the time of the interrupt. type in the BASIC . a program whose start address is stored in locations 788 and 789 is run. we can alter the display midway through a scan. but to use this knowledge we must make use of another VIC register . So far we have seen how we can get an indication of when the scanning electron beam reaches a given point on the screen. Bit 0 will remain set until you clear it by writing a 1 to that bit. here is a short machine code program which changes the background colour of the display half way down the screen. Bit 0 of the interrupt status register is set (Bit 7 is also set for any VIC interrupt). To illustrate the technique. The Interrupt Status Register When the current raster position equals the stored value.

exit STA INTREG raster interrupt 370 LDA RASREG 380 .Part 2 loader pro gram which follows the assembly language listing. 290 ! 300 ! PROG examine interrupt register LDA INTREG 350 AND #1 for bitO=1? 360 BEQ NORMAL ifnot. IRQ vectors 100 IRQLO=788 IRQHI=789 110 120 RASREG=53266 Raster register IENREG=53274 Interrupt enable 130 SCREEN=53281 Screen colour reg 140 INTREG=53273 Interrupt status 150 160 IRQVEC=59953 default IRQ vector 170 ! SETUP SEI disable interrupts 180 LDA #<PROG load IRQ vectors with 190 address of new program 200 STA IRQLO LDA #>PROG 210 220 STA IRQHI LDA #1 set bit 0 of interrupt enable 230 register 240 STA IENREG initialise raster register 242 LDA #0 244 STA RASREG including bit 81 245 LDA 53265 246 AND #127 247 STA 53265 CLI enable interrupts 250 RTS back to BASIC 260 270 ! 280 ! ifwe get here an interrupt has occurred.clear RASREG 382 BNE RR if< >0 then branch 384 next interrupt is half way LDA #145 STA RASREG down the screen 386 change screen colour STA SCREEN 388 390 JMP RR2 exit 392 RR LDA #0 next interrupt is at the top ofthe screen STA RASREG 394 .304 The Commodore 64 Omnibus . 3 DATA which loads the code into the cassette butTer. 45 DATA .20.141.141. Notice that the I flag is set to prevent any interrupts occurring while the program is running (and cleared afterwards!). DATA 3.173. runs it and clears i tself from memory.104.18. 25.D NEXT Z SYS 828:NEW DATA 120.234 How the Program works Lines 180 to 260 load the IRQ vectors with the start address of the new routine and initialise the registers. DATA 208. 5 10 20 30 40 50 20000 20010 20020 20030 20040 REM BASIC LOADER FOR INTERRUPT DEMO FOR Z=828 TO 901 READ D POKE Z. Interrupts 396 420 421 422 423 424 425 NORMAL STA SCREEN RR2 PLA TAY PLA TAX PLA RTI JMP IRQVEC 305 change colour restore values in registers before interrupt end handle other interrupts Here is the BASIC loader for the program.1.

Part 2 The interrupt program itself starts at line 340 by checking for Bit 0 of the interrupt register being set. and the screen colour is set to 0 which is black. and can be disabled by pressing RUN/STOP and RESTORE. Ifit is not then the interrupt wasn't generated by araster compare routine and control is passed to the normal interrupt routines by line 440. Bit 0 of the interrupt register is cleared and the contents ofthe raster register are examined. If you run the pro gram you will see that the top half of the screen will be whi te while the bottom is black. the accumulator.306 The Commodore 64 Omnibus . Ifthe interrupt was at the middle ofthe screen (Le. the raster register contained 145). This is because each time you press a key an interrupt is generated. In this case the raster register is loaded with 145 (corresponding to a position half way down the screen . If the interrupt occurred at the top of the screen then the raster register will contain zero. If the running of this routine coincides .the position where we want the next interrupt to occur) and the screen colour is changed to white. X and Y registers are retrieved from the stack where they were placed by the 64's in terrupt handling routines. calling the new interrupt routine before control is passed to the 64's routine at 59953. the raster register is cleared so that the next interrupt happens at the top of the screen. Before returning from the routine. If araster interrupt has occurred. Once running it will have no effect on your BASIC pro grams. You will notice that the screen flickers slightly and that the rate of flicker increases when you press a key.

This technique is used in the next program to display 8 standard sprites and 8 multicolour sprites on the screen at the same time! An Abundance of Sprites! 10 15 20 25 30 40 50 60 70 100 110 120 130 150 160 170 175 . but can be minimised as you will see in later examples..************** .· * * . . POINTER=2040 YPOS=53249 SMCREG=53276 IRQLO=788 IRQHI=789 RASREG=53266 IENREG=53274 INTREG=53273 IRQVEC=59953 *=$COOO SEI LDA STA LDA STA #<PROG IRQLO #>PROG IRQHI .. 180 SET 190 200 210 220 .Display Interrupts 307 with the processing of a key press then araster interrupt will be tmissed' and the screen will flicker. As we mentioned earlier raster interrupts can be used to create effects not possible by any other means. For example you could display text in different fonts on different parts of the screen by having several character sets in RAM and arranging your interrupt routine to change the character set pointer when araster interrupt occurs. This effect is particularly noticeable with this example.· * * .************** ·.* 16 sprites * .

X LOOP #200 #14 .X STD #14 #70 YPOS.308 The Commodore 64 Omnibus .Part 2 230 240 242 244 245 246 247 250 260 270 300 310 320 330 340 350 360 370 380 390 400 410 420 421 422 424 425 426 427 430 440 450 500 510 520 540 550 570 580 581 582 LDA STA LDA STA LDA AND STA CLI RTS PROGLDA AND BEQ STA LDA BNE LDA STA LDX STD LDA STA DEX BPL LDX LDA Y1 STA DEX DEX BPL LDA STA JMP MULT LDA STA LDX LDA LOOPSTA DEX BPL LDA LDX #1 IENREG #0 RASREG 53265 #127 53265 INTREG #1 NOR INTREG RASREG MULT #145 RASREG #7 #14 POINTER.X Y1 #0 SMCREG EXIT #0 RASREG #7 #13 POINTER.

202 . 249.202 .X Y2 #255 SMCREG IRQVEC The next pro gram is a BASI C loade r for the mach ine code.208 .1 73. 25.169 .1 57.2 08.Display Interru pts STA 584 Y2 DEX 585 DEX 586 BPL 587 LDA 590 STA 600 610 EXIT PLA TAY 620 PLA 630 TAX 640 PLA 650 RTI 660 670 NOR JMP 309 YPOS.12 7.7 .16.1 62.14 1.1 8. 141.3.D NEXT Z REM DATA 120.1 41. 18.4 1.26 .4 1. 169. 169.9 6 .14 1.202 . 0.20 8.18 .169 20040 DATA 70. 192 10 20 30 40 50 20000 .1 57.2 40.28 .3 .14 1. 21. REM LOADER FOR 16 SPRIT E DEMO FOR Z=49 152 TO 49271 READ D:POKE Z. 192.208 .16.1 69.88. 0.1 62.7 9.7 .1 .76. 17.2 08.173 .2 48. 169.2 08.2 08.208 20010 DATA 169.2 48. DATA 20020 141.173 25. DATA 20030 14.169 .208 .20 8.1.34 .2 0.14 1. NOTE: The code occup ies the same area of memo ry as the graph ics routin es.1 11.17 .1 45 141.1.208 . which will be overw ri tten.1 4 . 31.

1 POKE 53286. 104 20070 DATA 168. 169 20060 DATA 200. 202.13.76. 169. the sprite data polnters are switched to use another set of data and multicolour mode is selected.162.104.18.Part 2 310 20050 DATA 169.255 PRINT"{CLS}{YEL}HERE ARE 8 STANDARD SPRITES" FOR DE=O TO 1000:NEXT SYS 49152 . the only difference is that when the scan is half-way down the screen the sprite Y position re~sters are changed to 200.170. To see the effect of the interrupt program. NEXT I FOR I=O TO 7 POKE 53287+I.234 You will see that the program is very similar to the last one.208.D:NEXT FOR I=2040 TO 2047 POKE I.208.162. 49.2 POKE 53285.141.250.14:NEXT FOR I=O TO 14 STEP 2 POKE 53248+I.104.7.25+(15*I) POKE 53248+I+l. NEXT:POKE 53294.14.141.2 POKE 53269.The Commodore 64 Omnibus .249.169. enter it followed by this BASIC program: 1 5 10 20 30 40 60 70 75 80 90 100 110 120 130 140 150 160 170 REM 16 SPRITES ON ONE SCREEN DEMO POKE 53281.0 FOR I=O TO 127:READ D POKE 832+I.208.255.202.

1 70. 88.17 0.22 4.1 81.1 4.0.1 05.1 81 DATA 85. 255.40 .2 4.168 DATA 170. . 170 DATA 170.1 70.2 8.1 70.24. 254. 255 DATA 127. 255.25 5.6 0. 255.0 You could use this metho d to get even more sprite s on one displa y.1 26 DATA 24.25 5. 56.1 68.1 2.15 .85 .42 DATA 40.1 60.2 2 DATA 165.9 4.17 0.42 .122 .13 6. 192.175 .255 DATA .25 5. 255.96 DATA 126.24 .255 DATA 250.24 .2 40. 24 DATA 56.17 3.17 0.28.1 48. 28. 42.56 .40.13 6. 255.2 4.170 DATA 128.25 5.2 .1 12.48 .170.24.1 70.4 2.25 5.0 .0 .24 .5 6.94.170 DATA 168.2 55.90 .1 68.12 6.Display Interru pts 180 190 200 998 999 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 1999 2000 2010 2020 2030 2040 2050 2060 2070 311 PRIN T"{15 * CD}HERE ARE 8 M{WHT}U{RED}L{CYN}T{PUR}I{GRN} C{BLU}O{YEL}L{ORG}O{BRN}U{YEL} R SPRIT ES" PRINT"{CD}{CD}{CD}{CD}{CD} {CD} {WHT }IT'S ALL DONE WITH INTE RRUP TS!!" GOTO 200 REM REM DATA FOR MULTI COLOR SPRIT ES DATA 8. 6.15.85 .3 DATA 255. hut you would need a mach ine code progr am to move them aroun d satisf actori ly. 255.0.28 .4 2. 0.0 REM REM DATA FOR STANDARD SPRIT ES DATA 24.3 7 DATA 170.16 8 DATA 10.25 5.2 32.1 2.6 0.43 DATA 85.25 5.1 26.1 70.48. 7.25 5 DATA 255.

Raster interrupts can be put to use here by switching between bit-mapped mode and standard text mode at the appropriate place on the screen. That is how the split screen in the program demonstrating the graphics routines in Chapter 20 was created. Here is a listing of the split screen interrupt program and a BASIC loader: 100 IRQLO = 788 110 IRQHI = 789 120 RASREG = 53266 130 IENREG = 53274 140 INTREG = 53273 150 IRQVEC = 59953 160 LORES = 49266 170 HIRES = 49221 200 * = $C512 210 SETUP SEI 220 LDA # <PROG 225 STA IRQLO 230 LDA #>PROG 240 STA IRQHI LDA #1 250 STA IENREG 255 LDA #0 260 STA RASREG 265 270 LDA 53265 280 AND #127 290 STA 53265 300 CLI 310 RTS 500 PROG LDA INTREG 510 AND #1 .Part 2 MIXED MODE DISPLAYS One of the disadvantages of the 64's display compared with some other micros is that you cannot display text at the same time as high resolution graphics.312 The Commodore 64 Omnibus . Interrupts 520 530 540 550 560 565 566 570 600 TEXT 610 620 700 EXIT 710 720 730 740 750 800 NORM BEQ STA LDA BNE JSR LDA STA JMP JSR LDA STA PLA TAY PLA TAX PLA RTI JMP 313 NORM INTREG RASREG TEXT HIRES #200 RASREG EXIT LORES #0 RASREG IRQVEC The routine is loaded by the following BASIC pro gram and is located immediately after the graphics routines. 10 20 30 40 20000 REM MIX MODE LOADER FOR Z=50468 TO 50541 READ D:POKE Z. which obviously must be in situ for i t to work.18.18.208. 197.114.141 . 20010 DATA .3.20.11. 76.96.141. 208.D NEXT Z DATA 120. 20030 DATA 192.169. 173 20020 DATA


The Commodore 64 Omnibus - Part 2

20040 DATA 208,104,168,104,170,104,

To initialise the routine type:
SYS 50450

The display will now comprise a graphics screen
with a six line text window at the foot ofthe screen.
We have mentioned just a few of the ways raster
interrupts can be used to create more interesting
displays - it's up to you to adapt the principles to
suit your own applications.

In addition to setting Bit 0 when the current raster
position equals the stored raster position, the
interrupt status register provides an indication of
sprite collisions.
Bit 1 is set when asprite to data collision occurs
and will remain set until cleared. If the
corresponding bit in the interrupt enable register is
set, an interrupt will be generated. Similarly, Bit 2
will be set when asprite to sprite collision occurs.
No information is provided as to which sprite(s) are
involved - that must be done by your program. But
using interrupts means your pro gram does not
have to be constantly checking the sprite collision
registers so i t will run more quickly.
Interrupts are used in many ways by computers another example is in the pro gram in Chapter 22,
where movement of the joystick generates an
interrupt. This allows very smooth motion of the
cursor, and means that other pro grams can run at
the same time.


Writing pro grams to be used by other people is a
very different art from the writing of pro grams
which only you will use. Most people who use
pro grams written by others are not skilled in the
use of computers, and may not be familiar with the
typewriter keyboard. In this chapter we will look
at a few ideas for making pro grams easier to use making them ~user friendly' as thejargon puts it.

There are two si des to making programs userfriendly. They must allow the user to select options
easily and quickly, and they must also tell the user
what options are available at all times. A program
may have supporting documentation, but the
screen display should present enough information
for the pro gram to be usable without referring to
the notes once the basics have been learnt.

One of the simplest and most effective ways of
assisting the user to control the pro gram is the
menu. This is a list of the options available, with
some means of indicating how to select an option.
The simplest form presents the list with a key
legend next to each item, indicating that the key
should be pressed to select that feature. The
function keys of the 64 work weIl with this type of
menu; other possibilities are to use the initial letter


The Commodore 64 Omnibus - Part 2

of each option as the selecting key, or to use
A second form of menu displays the list as before,
but indicates the selected item by displaying it in a
different colour, or in inverse video. One or two
keys are then used to move the selection up and
down the list, and a third key acts as the ((go"
button, indicating that the selected item is to be
acted on. The cursor keys and the RETURN key
are probaby best in this application.

Mice and Pointers
The typewriter keyboard is far from the ideal
device for communicating with a computer for the
newcomer. Many people have no experience of
using a keyboard, and find using programs very
difficult if they are constantly searching for the
right key to press. In addition, the keyboard is not
always the best way of controlling a computer, even
for an expert. To get round these problems, there
are a number of different devices now being used to
allow the operator to make inputs by pointing at
symbols on the screen.
Perhaps the best known of these devices at the
moment is the mouse, a small box with a ballbearing underneath which moves a cursor around
the screen as the mouse is rolled about on the desk.
The mouse usually has one or two buttons on the
top which are used to make selections when the
cursor reaches the right point on the screen.
Other pointing devices which perform a similar
function are the light-pen, which detects the light
emitted by the screen and so may be used to point
directly at the screen, and the tracker ball, which
rolls a cursor round the screen. The latest
innovation is the touch sensitive screen, which

Programs and People


allows the humble human finger to select objects on
the display.
The type of display used with these devices may be
very different from that used in ordinary textual
menus. Ifthe user is making selections by pointing
at the screen, the display describing what is
available need not use text, but can use small
pictorial symbols to indicate options. These
symbols are called icons, and are used in several of
the most advanced business micros now on the

This program demonstrates the use of icons on the
64, using ajoystick to draw pictures in multicolour
bit-mapped mode.


POKE 53281,CO: POKE 686,Cl:
POKE 687,C2: POKE 688,C3
FOR 1=0 TO 383: READ X: POKE
23168+I,X: NEXT
50542+I,X: NEXT
FOR 1=53251 TO 53263 STEP 2:
POKE 1,225: NEXT
FOR 1=0 TO 12 STEP 2: POKE
53250+1,(24+24*1) AND 255:


The Commodore 64 Omnibus - Part 2


.•. {RVS} Fl {ROF}":
••• {LTRED}{RVS} F2
FROM DISK ••• {RVS} F3 {ROF}":
••• {RVS} F5 {ROF}":
. .. {RVS} F7 {ROF}":
... {LTRED}{RVS} F8
GET K$: IF K$="" THEN 1100
IF K$="{Fl}" THEN SYS 49177:
GOSUB 2010: GOTO 1000
IF K$="{F2}" THEN GOSUB 2000:
GOTO 1000
IF K$="{F3}" THEN GOSUB 5000:
SYS 49177: GOSUB 2010: GOTO
IF K$="{F5}" THEN GOSUB 6000:
GOTO 1000
IF K$="{F7}" THEN GOSUB 7000:
GOTO 1000
GOTO 1100
POKE 24568,106:POKE 24569,108

Programs and People



FOR 1=24570 TO 24572: POKE I,
107: NEXT
POKE 24573,109: POKE
24574,110: POKE 24575,111
POKE 53248,172: POKE 53249,120
POKE 53288,IC: POKE 53289,C1:
POKE 53290,C2: POKE 53291, C3
POKE 53292,IC: POKE 53293,IC:
POKE 53294,IC:POKE 53287,IC
POKE 53269, 255: REM TURN
POKE 53264,192: REM SPRITE X
SYS 50542: POKE690,1: REM TURN
POKE 53277,2+(FB+1): REM
POKE 685,FB: POKE 53281,CO
C=PEEK(53278): IF C=O THEN
IF (PEEK(56320) AND 16)<>0
THEN 2100
CC = C AND 254
IF CC=4 THEN FB=l: GOTO 2090
IF CC=8 THEN FB=2: GOTO 2090
IF CC=16 THEN FB=3: GOTO 2090
IF CC<>128 THEN 2100

The Commodore 64 Omnibus - Part 2



POKE 53281,6
POKE 690,0:POKE 53277,CC
IF (PEEK(56320)AND16) <> 16
THEN 3005
IF (PEEK(56320)AND16) <> 0
THEN 3010
X1=PEEK(691): X2=PEEK(692):
IF (PEEK(56320)AND16) <> 16
THEN 3030
IF (PEEK(56320)AND16) <> 0
THEN 3040
XL=PEEK(691): XH=PEEK(692):
GOSUB 3100
IF(PEEK(56320)AND16) <> 16
THEN POKE 685,0: GOSUB 3100:
POKE 685,FB: GOTO 3050
POKE 682,X1: POKE 683,X2: POKE
POKE 690,0:POKE 53277,CC
IF (PEEK(56320)AND16) <> 16
THEN 4005
IF (PEEK(56320)AND16) <>0 THEN
X1=PEEK(691): X2=PEEK(692):
IF (PEEK(56320)AND16) <>16
THEN 4030
IF (PEEK(56320)AND16) <>0 THEN

Programs and People



XL=PEEK(691): XH=PEEK(692):
GOSUB 4200:POKE 685,0: GOSUB
4200: POKE685,FB
IF (PEEK(56320)AND16) <>16
THEN 4050
GOSUB 4200
IF X1+256*X2>XL+256*XH THEN
T1=X1: T2=X2: X1=XL: X2=XH:
XL=T1: XH=T1
IF Y1>Y THEN T=Y: Y=Y1: Y1=T
POKE 679,X1:POKE 680,X2: POKE
SYS 50402
POKE 682,X1: POKE 683,X2: POKE
SYS 49608
SYS 49608
POKE 679,X1: POKE 680,X2: POKE
SYS 49608
POKE 682,X1: POKE 683,X2: POKE
POKE 679,X1: POKE 680,X2: POKE

The Commodore 64 Omnibus - Part 2



OPEN 1,8,2,F$+"S,R"
INPUT#l,Cl: POKE 686,Cl
INPUT#1,C2: POKE 687,C2
INPUT#1,C3: POKE 688,C3
FOR 1=24576 TO 32575
GET#l, 0$
IF 0$="" THEN D$=CHR$(O)
OPEN 1,8,2,F$+"S,W"
l":Cl:POKE 686,Cl
2"~C2:POKE 687,C2

Programs and People



3":C3:POKE 688,C3
20000 DATA 0,0,0,0,0,0,0,0,0,0
20010 DATA 24,0,15,255,240,12,24,48,
20020 DATA 12,0,48,12,0,48,12,0,48,
20030DATA 0,0,0,0,0,0,0,0,0,0,0
20100 DATA 0,0,0,31,192,60,127,252,
20110 DATA 255,255,255,255,63,255,
20120 DATA 255,252,127,255,248,63,
20130 DATA 15,255,255,3,255,231,0,
20140 DATA 192,60,63,252,254,112,
20150 DATA 48,0,3,48,0,7,112,0,6,96,
20160 DATA 24,48,0,12,24,0,12,24,0,
20170 DATA 252,103,0,63,224,0,7,192,
20180 DATA 0,28,0,0,14,0,0,7,0,0,3,
20190 DATA 224,0,0,112,0,0,56,0,0,
20200 DATA 0,3,128,0,1,192,0,0,224,
20210 DATA 28,0,0,14,0,0,0,0,0,0,0,
63,255,252,63,255,252 3. 208.19.179 .0. 72. 20280 DATA 252.48. 20520 DATA The Commodore 64 Omnibus .48. 20240 DATA 63.16.0 24990 REM DATA FOR MACHINE CODE 20500 DATA 120.48 20260 DATA 0.173 20530 DATA 16.173. 20540 DATA 233. 20550 DATA 176.0.9. 197. 20230 DATA 252. 63.74 20510 DATA 20270 DATA 48.51.29. 12. 20250 DATA 0.63. 204.Part 2 20220 DATA 20560 DATA 20570 DATA How to use the program This program uses the machine code graphics routines introduced in Chapters 18 and 19. When you run the program.74.49. The joystick is used to move a cursor around the multicolour bit-mapped display.88. 2.2. which are selected by the function keys: Show Current Picture: This will change the display to bit-mapped mode without clearing the bit-mapped screen. 20. which must be plugged into control port 2 at the right hand side of the 20600 DATA 167.41. .141. Appendix 18 gives full instructions on how to do this.141. 179. and the fire button of the joystick plots points on the screen.180 20590 DATA 2.178.2. N ew Picture: This clears and displays the bit-mapped screen.2.Programs and People 325 20580 DATA 20610 DATA 76. The machine code must be loaded into the 64 be fore this program is run. after a shortpause while the data is read. The program requires a joystick. a menu is displayed offering you the following options.

the next point at which you fire will be the start of the line. and to use the line drawing and block filling routines. The icons are used to select different line colours. and holding down the fire button will cause points to be plotted under the cursor. The four left-hand icons represent blobs of paint. The sixth icon (the F) is used in a similar way to fill blocks on the screen.Part 2 Load Picture: Loads previously sa ved pictures from the disko Save Picture: Sa ves the curren t bi tmapped picture on to the disko Change Colours: Allows you to change the colours of the display and the icons. Once this is selected. The selected icon will expand to twice its normal width. The two fire pushes after . The fifth icon (the line) is used to select line drawing mode. Stop Program: Stops the program! Selecting ei ther of the first two options displays a multicolour bit-mapped screen with seven icons at the bottom and a cross-hair cursor in the middle. and are used to select the line colour.326 The Commodore 64 Omnibus . and the line will be drawn. and pressing fire again will mark the line end. Moving the joystick will move the cursor. Simply fire at the appropriate icon to change the colour. Ifyou hold down the fire button while marking the li ne end a line will be flashed on and off. when the line will be drawn in the currently selected colour. and will follow the cursor around until you release the button.

The seventh icon represents the main menu.Programs and People 327 selecting the fill icon will mark diagonally opposite corners of the rectangle to be filled. This machine code is incl uded in the DAT A statements in lines 20500 to 20610. 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 260 270 280 290 300 IRQLO IRQHI XL XH Y = = = = = CURSORXL CURSORXH CURSORY 788 789 64 interrupt vector stored here 679 680 681 Co-ordinates for plot = = = Cursor sprite coordinates 691 692 693 IRQVEC = 14 = 75 = 41 = 239 = 59953 PLOT PLOTOK = = XMIN XMAX YMIN YMAX $COB8 690 Maxand min cursor co-ordinates Normal interrupt address Plot routine Plot on/off . and is loaded into memory when you run the program. and is used to return there. The 64's sprites are used as the icons and the cursor. This pro gram is listed below. The program uses an additional machine code routine to move the cursor and to plot on the bitmapped screen when the joystick fire button is pressed. The collisions detection facili ty of the VIC chip is used to check whether the cursor sprite is over one ofthe icon sprites.

Part 2 328 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 710 JOYREG = 56320 SPRXL SPRXH SPRY * = J1B J2 J2B J3 53248 53264 53249 $C56E SETUP PROG = = = SEI LDA STA LDA STA CLI RTS LDA LSR BCS PHA LDA CMP BCC DEC PLA LSR BCS PHA LDA CMP BCS INC PLA Joystick port Cursor (sprite 0) position registers Starts at 50542 Reset interrupt uector #<PROG to point at this IRQLO program #>PROG IRQHI JOYREG Readjoystick port A J2 Branch if bit 0 set SPRY #YMIN J1B SPRY Stick held up Ifnotat top moue cursor up A J3 Branch if bit 1 of joystick port set SPRY #YMAX J2B SPRY Stick held down If not at bottom moue cursor down LSR A BCS J4 Branch if bit 2 ofjoystick port set .The Commodore 64 Omnibus .

Programs and People 720 730 740 750 760 770 780 790 800 810 820 830 840 850 860 870 880 890 900 910 920 930 940 950 960 970 980 990 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 J3A J3B J4 J4A J4B J5 PHA LDA AND BNE LDA CMP BCC SEC LDA SBC STA BCS LDA AND STA PLA SPRXH #1 J3A SPRXL #XMIN J3B 329 Stick held left If not at left-hand edge of screen moue cursor left SPRXL #1 SPRXL J3B SPRXH #254 SPRXH LSR BCS PHA LDA AND BEQ LDA CMP BCS INC BNE LDA ORA STA PLA A SPRXH #1 J4A SPRXL #XMAX J4B SPRXL J4B SPRXH #1 SPRXH Stick held right If not at right-hand edge of screen moue cursor right LSR BCS SEC LDA SBC STA SEC LDA A EXIT Branch ifbit4 of joystick port set J5 B ranch if bit 3 of joystick port set SPRY Fire button down #40 resetplotco-ordinates CURSORY SPRXL .

330 The Commodore 64 Omnibus .Part 2 1130 1140 1150 1160 1170 1180 1190 1200 1210 1220 1230 1240 1250 1260 1270 1280 1290 1300 1310 1320 1330 1340 1350 1360 EXIT 1370 1380 1390 1400 RESET 1410 1420 1430 1440 1450 1460 SBC STA LDA SBC AND STA LDA LSR STA LDA ROR STA LDA BEQ LDA STA LDA STA LDA STA JSR #12 CURSORXL SPRXH #0 #1 CURSORXH CURSORXH A CURSORXH CURSORXL A CURSORXL PLOTOK Check ifplot allowed EXIT If not branch CURSORXL XL CURSORXH XH CURSORY Y PLOT Plot pixel JMP IRQVEC Jump to normal interrupt routine SEI LDA STA LDA STA CLI RTS #<IRQVEC IRQLO #>IRQVEC IRQHI Disable routine by resetting interrupt vector to point to normal interrupt handler .

CHAPTER 23 SOUND AND MUSIC . This chapt er cover s some ofthe ways in which the 64 can be used to play tunes and melod ies. each with a range of eight octav es.the SID chip. THE SID CHIP The SID chip provi des the 64 with three voice s.PART 2 Soun d adds anoth er dime nsion to pro gram s maki ng them more intere sting and excit ing or more user friend ly. The soun d so produ ced may be heard eithe r throu gh the TV speak er or fed to a hi-fi system . One way of doing this is show n in this exam ple: 1 10 20 30 40 50 500 GOSUB 1000 LO=I NT(R ND(1 )*256 ) HI=IN T(RN D(1)* 256) GOSUB 500 FOR D=O TO 50:NE XT D GOTO 10 REM CHANGE NOTE . which can be indep enden tly progr amme d to produ ce an almos t infin ite varie ty of wave form s. Playi ng Tune s To get the 64 to play tunes . you must 'feed' the SID chip with the appro priate frequ ency data for the notes comp rising the tune. in the correc t order and at the correc t speed . by explo iting the capab ilites of its builtin synth esiser .

168:REM SUST/REL 2040 POKE 54283.33:REM CONTROL REG 2050 RETURN 2099 REM SET UP SID CHIP REG 3 3000 L3=54286:REM LOW 3010 H3=54287:REM HIGH .168:REM SUST/REL POKE 54276.LO/2:POKE L3.33:REM WAVEFORM 1060 RETURN 1999 REM SET UP SID CHIP REG 2 2000 L2=54279:REM LOW 2010 H2=54280:REM HIGH 2020 POKE 54284.168:REM SUST/REL 1050 POKE 54276.HI/2:POKE H3.LO/4 40 POKE H1.LO:POKE L2.15:REM VOL 1010 L1=54272:REM LOW 1020 'H1=54273:REM HIGH 1030 POKE 54277.54:REM ATTACK/DECAY 2030 POKE 54285.54:REM ATTACK/DECAY POKE 54278.33:REM WAVEFORM RETURN This idea can be extended to cover all three channels like this: 1 GOSUB 1000:GOSUB 2000:GOSUB 3000 10 LO=INT(RND(1)*256) 20 HI=INT(RND(1)*256) 30 POKE L1.HI:POKE H2.HI/4 50 FOR D=OT050:NEXT D GOTO 10 60 999 REM SET UP SID CHIP REG 1 1000 POKE 54296.54:REM ATTACK/DECAY 1040 POKE 54278.LO POKE 54273.15:REM VOL POKE 54277.HI RETURN REM SET UP SID CHIP POKE 54296.332 The Advanced Commodore 64 Handbook 510 520 530 999 1000 1030 1040 1050 1060 POKE 54272.

The table on page 152 of the Commodore 64 User Guide gives a list of frequency values corresponding to musical notes (if you are unfamiliar with musical notation refer to Appendix 9).l» HI=ASC(MIO$(H$.l» GOSUB 500 FOR x=o TO 100:NEXT X HI=O:LO=O:GOSUB 500 NEXT Q STOP REM CHANGE NOTE POKE 54272.HI RETURN REM SET UP SIO CHIP POKE 54296.54:REM ATTACK/OECAY .15:REM VOL POKE 54277.33:REM WAVEFORM RETURN N ei ther of these examples could be described as music .54:REM ATTACK/OECAY POKE 54292. but can they be stored? One way is to keep them in astring.Q. Using this table you can build up aseries of numbers corresponding to the high and low bytes of the frequency of the notes. reading them one at a time and POKEing them into the appropriate SID registers. This technique is illustrated in the following program: 1 10 20 30 40 50 60 70 80 90 100 500 510 520 530 999 1000 1020 GOSUB 1000 L$="%%%%?**%%/%" H$="{CO}{CO}{CO}{CO}{HOM} {RVS}{RVS}{CO}{CO}"+CHR$(16)+" {CO}" FOR Q=l TO LEN(L$) LO=ASC(MIO$(L$.LO POKE 54273.for that we need a more controlled way of calculating the note frequencies.168:REM SUST/REL POKE 54290.c .Part 2 3020 3030 3040 3050 333 POKE 54291.Sound and Mus.Q.

one for each voice. Multi Channel Music You can easily expand the DATA statement method to cater for tunes using all three voices. 25 70 L$="32132121214" FOR D=O TO 100*VAL(MID$(L$. An extra problem occurs when a note on one voice is of a different length to that on another.334 The Advanced Commodore 64 Handbook 1030 1040 1050 POKE 54278. but a better way is to hold information concerning notes and note lengths in DAT A statements. which renders it impractical for all but the simplest oftunes. Add these lines to the last program to hear this technique in action. re du ce each note to the shortest common length and playanote several times if it is longer than this. perhaps wi th different A ttack/Decay and Sustain/Release characteristics to simulate different musical instruments. To overcome this you could use three duration loop counters. This technique is illustrated in the pro gram at the end of this chapter. or.Q. in which data for high and low frequencies is held in DATA statements. . 1) ) : NEXT D This method is adequate for simple tun es. There are several ways of overcoming this. more simply. You can see an example ofthis technique in the program at the end of the chapter.33:REM WAVEFORM RETURN The main limitation of this method is that the notes are all the same length. For example.168:REM SUST/REL POKE 54276. a second string could be used to hold the data for the length of notes.

as the next program illustrates. 1 100 110 120 130 140 150 160 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1015 1020 1030 1040 1050 1060 1070 1075 1080 1090 1092 1093 1094 1096 1097 *=$COOO VOICEILOW=54272 VOICEIHIGH=54273 ATTDEC=54277 SUSREL=54278 CONTROL=54296 NOTES=679 INIT PLAY LOOP LDX LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA INX LDA STA INX LDA INX TAY JSR LDA STA LDY DEY BNE #0 #13 NOTES #15 CONTROL #54 ATTDEC #168 SUSREL #33 54276 TABLE.c .X DELAY #32 54276 #255 LOOP . since all you have to do is duplicate the BASIC POKEs to achieve the same effect.Part 2 335 MUSIC FROM MACHINE CODE PROGRAMS Using the SID chip from within machine code pro grams is very easy.Sound and Mus.X VOICEILOW TABLE.X VOICEIHIGH TABLE. However since machine code is so much faster than BASIC you could introduce such tricks as altering the volume of a note or changing the waveform. This me ans you don't have to rely on a table to calculate the frequencies you need for a particular tune: you can get the 64 to do it for you. BYT could even have the 64 play soothing music as you type in a program!! Calculating Note Frequencies The frequencies of musical notes are governed by mathematical rules .25. dynamically.for example any note is exactly twice the frequency of the same note in the octave below. 227. 2.1.28 .17.63.2. 2.177. Another possibility is to use interrupts to allow tunes to be played while other actions are being performed .The Advanced Commodore 64 Handbook 336 1100 1110 1120 1130 1140 1150 1160 2000 2010 2015 2020 2030 2040 2050 5000 5010 QUIET DELAY TIME DEC BNE LDA STA LDA STA RTS LDA STA LDA BPL NOTES PLAY #32 54276 #0 54296 #100 162 162 TIME DEY BNE DELAY RTS TABLE BYT 177.17.

Sharps and flats can be specified by adding the # or b symbol to the note when you type i t in .l»:lF P<>35 ANO P<>45 THEN EF=l RETURN REM REM ************** REM * * REM * CALC PlTCH * REM * * REM ************** REM lFN>l THEN N=N-2:GOTO 2020 N=N+5 N=N*2 lF N>4 THEN N=N-1 lF P=35 THEN N=N+1 . 10 992 993 994 995 996 997 998 1000 1010 1020 1030 1040 1992 1993 1994 1995 1996 1997 1998 2000 2010 2020 2030 2040 OlM TO%(2.Sound and Music .2. which is note C from the third octave.N$(199):Hl=0: LO=O:GOTO 15000 REM REM ************************** REM * * REM * CALCULATE NOTE.1»-65:lF N<O OR N>6 THEN EF=l:GOTO 1040 0=ASC(MlO$(Z$.C4#.199). OCTAVE * REM * * REM ************************** REM N=ASC(LEFT$(Z$. The note is played and the numbers and notes stored in the array TD%. The strings describing the notes are stored in the arrayN$. and displays the appropriate frequency numbers for the SID chip to play that note.1»-48:lF 0<0 OR 0>7 THEN EF=l:GOTO 1040 lF LEN(Z$)=2 THEN P=O:GOTO 1040 P=ASC(RlGHT$(Z$.Part 2 337 The next program is a simple music editor which allows you to enter a note and its octave in the form C3.

Z$ L=LEN(Z$):IF L<2 OR L>3 THEN 15000 15030 GOSUB 1000 15040 IF EF=l THEN EF=O:GOTO 15000 15050 GOSUB 2000 .54:REM ATTACK/OECAY POKE 54278.HI RETURN REM REM *************** REM * * REM * ENTER NOTES * REM * * REM *************** REM GOSUB 10000:REM SET UP SIO PRINTls": INPUT "NOTE".168:REM SUST/REL POKE 54276.15 POKE 54272.LO POKE 54273.338 The Advanced Commodore 64 Handbook 2050 2060 2992 2993 2994 2995 2996 2997 2998 3000 3010 3020 3030 9992 9993 9994 9995 9996 9997 9998 10000 10010 10020 10030 10040 10050 10060 14992 14993 14994 14995 14996 14997 14998 15000 15010 15020 IF P=45 THEN N=N-l RETURN REM REM ******************** REM * * REM * CALC FREQ VALUES * REM * * REM ******************** REM F=(274*(2tO»*2t(N/12) HI=INT(F/256) LO=INT(F-HI*256) RETURN REM REM ******** REM * * REM * PLAY * REM * * REM ******** REM POKE 54277.33:REM WAVEFORM POKE 54296.

L2.Part 2 15060 15070 15080 15085 15090 15095 15100 15110 339 GOSUB 3000 PRINT"HIGH FREQUENCY=":HI PRINT"LOW FREQUENCY=":LO TD%(O.54:REM ATTACK/DECAY POKE 54285.L1 POKE 54280.L1.191:REM SUST/REL POKE 54276.33:REM CONTROL REG RETURN REM SET UP SID CHIP REG 3 POKE 54291.15:REM VOL POKE 54277.Z)=LO: N$(Z)=Z$ GOSUB 10040: Z=Z+l PRINT "PRESS ANY KEY TO CONTINUE" GET K$:IF K$="" THEN 15100 HI=O:LO=O:GOSUB 10040:GOTO 15010 PICTURES AT AN EXHIBITION This program plays a piece of classical music in three part harmony to demonstra te some of the techniques covered in this chapter.H1:POKE 54272.L2 POKE 54287.H2:POKE 54279.54:REM ATTACK/DECAY POKE 54278.54:REM ATTACK/DECAY . A lot of typing is involved hut the end result is worth it! 1 10 15 20 30 40 50 60 999 1000 1030 1040 1050 1060 1999 2000 2010 2020 2030 2099 3000 GOSUB 1000:GOSUB 2000:GOSUB 3000 READ H1.33:REM WAVEFORM RETURN REM SET UP SID CHIP REG 2 POKE 54284.L3 FOR D=O TO 120:NEXT D GOTO 10 REM SET UP SID CHIP REG 1 POKE 54296.H2.H3:POKE 54286.168:REM SUST/REL POKE 54283.Sound and Music .L3 IF H1=999 THEN END POKE 54273.H3.Z)=HI:TD%(l. DATA REM *********************** DATA 17.63. WAVEFORM RETURN DATA The Advanced Commodore 64 Handbook 3010 3020 3050 10000 10010 10020 10025 10030 10040 10050 10055 10060 10070 POKE 54292.63.168:REM SUST/REL POKE 54290. 37. DATA 11. 10090 DATA REM *********************** DATA 10120 DATA 17.0.0 DATA 0. . 10080 DATA 10095 REM *********************** 10100 DATA 9. 0.37.114 10110 DATA DATA DATA 227. 0.205. 9.

0 10250 DATA 10235 REM ************************ 10240 DATA 15. 0.8.0. and Music . 10165 REM ************************ 10170 DATA 10205 REM ************************ 10210 DATA 0.22. 10190 DATA 19. 11.0.56. 10150 DATA 10220 DATA . 6.Part 1 341 10130 DATA 12.0.0. 10135 REM ************************ 10140 DATA 11.0.0. 0. 10180 DATA 227.0.0 10160 DATA 10230 DATA 10200 DATA 10275 REM ************************ 10280 DATA 10270 DATA 10300 DATA 10370 The Advanced Commodore 64 Handbook 10260 DATA 22.156 10355 REM ************************ 10360 DATA 10350 DATA DATA 10290 DATA 10340 DATA 42. 10380 DATA 37.163 .22.2. 70. 7.37.3. 70.156. 10385 REM ************************ 10390 DATA 10310 DATA 60. 13.60.156 10330 DATA 10315 REM ************************ 10320 DATA 18.156. 10.37. 60.60.

163 10480 DATA 2 343 10400 DATA 19. 227.4. 19.154. 10450 DATA 10460 DATA 10420 DATA 10500 DATA 28.19. 216.208 . 10505 REM ************************ 10510 DATA 22. 227.170. 154.25.220 10490 DATA 154. 216.14.3. 15.11.7. 141. 214.0.75. 63. 10520 DATA 19.54. 12. 2.53 10410 DATA and Music . 70.70 10425 REM ************************ 10430 DATA 10465 REM ************************ 10470 DATA 10440 DATA 34.12.

37.11.159 10600 DATA 14.15. . 10585 REM ************************ 10590DATA 10700DATA 22. 11.22. 11.70.208 10540DATA 17.3.14. 2.37.70. .159 10715 REM ************************ 10720DATA 17. 37.107. 141.12. 15.216 10710DATA 9.227. 70.12 10730DATA 10570DATA 10545 REM ************************ 10550DATA 10560DATA 107.114. 17.344 The Advanced Commodore 64 Handbook 10530 DA TA 19.147 10580DATA 9.216. 10740DATA 2 345 10750 DATA 22.100. 227. 177.3. 227.54 10800 DATA 10755 REM ************************ 10760 DATA 22.220.22. 11.185.0. 177.11.159 10775 DATA 17.177.163 10850 DATA 12. 10815 REM ************************ 10820 DATA and Music . 108.37.216. 10810 DATA 6.3.159 10776 DATA 19.22. 216.216. 10777 REM ************************ 10780 DATA 25.15.216 10770 DATA 10830 DATA 7.0.54 10840 DATA 3.154. 10790 DATA 22. 10855 REM ************************ . 9.114.14. 10935 REM ************************ 10940 DATA 10930 DATA 227.114.8. 11.0.12. 7.159 10960 DA TA . 10970 DA TA 227. 7.63. 9.114 10950 DATA 216.147 10910 DA TA 7.159 50000 DA TA 0.0.114 10870 DATA 22.114 10880 DATA The Advanced Commodore 64 Handbook 10860 DATA 15.205.53 10920 DA TA 100.147. 9. 10895 REM ************************ 10900 DATA 10890 DATA

High Byte for voices one. especially classical music.Sound and Music . Arranging music. two and three. for the 64 often involves a good deal ofpruning to make it work with only three voices .Part 2 347 The frequency data is stored in the order Low Byte.very little of it was composed with the SID chip in mind! .

Because the disk is rotating. a flexible disk of plastic coated with magnetic material and enclosed in a protective envelope. The storage medium is the floppy disk. this arrangement me ans that any portion of the disk can be reached . and move it to and fro along the slot cut in the disk envelope. which uses the 5 pin socket on the back of the computer. Never switch the drive on or offwith a disk in place. Connecting the Disk Drive The disk drive connects to the 64 via the serial bus. and random access to data. The principal advantages of floppy disks over cassette tapes are greatly increased speed of data retrieval. A special motor called a stepper motor controls the movement of a readlwrite head similar to the one used in the cassette unit. A suitable cable is supplied with the disk drive. The mechanics are used to hold a disk firmly in place when the door is closed and to rotate the disk at approximately 300 rpm.CHAPTER 24 TH E 1541 DISK DRIVE The 1541 disk drive provides a means of storing and retrieving programs and data in a more flexible way than is possible with the cassette unit. Always switch on the disk drive before the 64. The stepper motor can pI ace the head in contact with the disk. HOW TH E DISK DRIVE OPERATES The 1541 disk drive unit contains both mechanical and electronic parts. to avoid damage to the computer.

Data Storage on Floppy Disks Data is stored on a disk in a number of concentric tracks each of which is divided into a number of sectors. The diagram on the next page shows how the tracks are arranged. The 2k of RAM is arranged into 256 byte buffers. a 6502. . which is very similar to the 6510 in the 64. track 1 being outermost. The processor has some RAM memory and a program known as a disk operating system stored in ROM. One advantage of having the DOS resident within the disk drive is that for many operations the transmission of the appropriate command to the DOS is all the computer needs to do.the outermost tracks have 21 sectors while track 35 has only 17 sectors. The Disk Operating System The disk operating system or DOS is contained in 16k ofROM in the disk drive. The exact number of sectors per track varies. and any data transfers between computer and disk drive occur via these buffers. This controls all the mechanical functions of the drive and the interface with the computer.The 1541 Disk Drive 349 by the head. Each track is divided into a number of sectors which can store a block of data 256 bytes. The DOS carries out the operation leaving the computer free for other tasks. since the tracks are of unequallength . A disk for use in a 1541 drive has 35 tracks. There are also some chips to control the interface between the disk drive and the 64. The head can read data from and write it to the disko The 1541 contains its own microprocessor.

17 21 18 .30 18 31 .Part 2 TRACK NUMBER NUMBER OF SECTORS 1 . each sector contains information used by the DOS for various .350 The Commodore 64 Omnibus .24 20 25 .35 17 Sector Distribution by Track The Arrangement ofTracks and Sectors In addition to the data bytes.

However t the penalties for not observing them are rather more severe! . Care of Floppy Disks Floppy disks are rather more delicate than cassette tapes t and to prevent damage great care must be taken when handling and storing them. c) Keep disks away from heat or sunlight. By following the guidelines in this section you will minimise the risk oflosing your valuable programs or data. d) Never write on the diskts plastic jacket . a) Always return the disk to its envelope immediately after use t and keep disks in a sturdy box designed for the purpose.The 1541 Disk Drive 351 housekeeping functions and to indicate on which track and sector the next block of data for a file is located.fill in sticky labels before applying them to the disko e) Do not touch the surface of the disk or try to clean it. f) Remove disks from the drive before switching it on or off. b) Do not store disks near magnetic fields (such as those generated by the TV)t since stray magnetic fields can destroy data. With the exception of the danger from magnetic fields t the rules for looking after floppy disks are similar to those for audio records.

Part 2 Formatting Blank Disks The 1541 disk drive uses standard 5.8. The disk drive will start to make a noise and the cursor will reappear leaving the 64 free for use while the DOS program formats the disko The process involves the clearing of any old data from the disk and the setting up of the 683 blocks for data storage. you must open a channel. Before you can use a new disk it must be prepared. can be abbreviated to its first letter.A1":CLOSE 15 would work equally weIl. The channel number 15 is reserved for communications with the disk unit. and is carried out by the DOS. To pass instructions to the drive. in common with all other DOS commands."NEW:TEST DISK. The formatting operation defines the tracks and sectors ofthe disk.352 The Commodore 64 Omnibus . To format the disk type: OPEN 15. some of these blocks are devoted to a . The NEW command.15 PRINT#15."N:TEST DISK. Ask your dealer for single sided single density disks. in the same way as you would to send data to the cassette unit or any other peripheral device. by a process called formatting to enable the DOS to store data on it. To keep track of what is saved on the disk. so: PRINT#15.A1":CLOSE 15 These two commands will open the disk command channel and send the NEW command to the disk drive.25 inch floppy disks.

15 PRINT#15. If you have a disk containing pro grams you no longer require (be certain!!). the maximum number ofblocks is available for use (664*256 bytes = 169984 bytes of storage). You can now examine the directory of the disk by typing: LOAD "$". there is no need to do so again. Clearing the Directory Once a disk has been formatted. which holds the disk name (in this case TEST DISK.8 LIST You will see the disk name and identifier in inverse video. Because nothing has been stored on the disk yet."NEW:RECLAIMED DISK" . after which disk activity will cease. you can clear the directory by using the NEW command but omitting the disk ID: OPEN 15. but any two characters are allowed) which enables the DOS to uniquely identify the disko The formatting operation takes about 80 seconds.8. The characters (2A' indicate which version of the DOS program was used to format the disk: this is the same for all 1541 drives.The 1541 Disk Drive 353 directory. and the words (664 blocks free'. and there are no entries in the directory. but you could use any name ofup to 16 characters) and a list of all the files on the disko Each block on the disk is labelled with the disk identifier (in this case Al.

the remainder is given over to a bit map of the 683 blocks on a disko Each bit in a byte of the BAM represents a block of data on the disko If the bit is set then the block is available for use.143 BAM Bit map of blocks used in tracks 1 .35 USE The BAM Format The first four bytes of the BAM are used by the DOS as storage for information about the disk. but will change the directory he ader and make an the sectors available for use so that you can write over any existing data. track 18 sector 0 is reserved for a map of the available sectors of each track on the disko This map is known as the block availablity map or BAM. TH E BLOCK AVAILABLITY MAP (BAM) The DOS needs to know which of the sectors of a disk have not yet been used.01 Pointer to Track & Sector of first Directory Block 2 65 ASClI'A' indicates disk format 3 0 Not used 4 . if not then . so that maximum use can be made of the space available.Part 2 354 This will not clear the disk. The arrangement of data in the BAM is shown in the diagram below: BYTE CONTENTS 0. 1 18. To keep track ofwhat's left.The Commodore 64 Omnibus .

8 You can save a revised version of a pro gram so that it replaces the old one with the same name on the disko To do this insert an @ in the command like this: SAVE "@:BEAN SHOOT". The BASIC commands LOAD and SA VE are used in the same way as they are with the cassette unit.8 Machine code pro grams or blocks of data can also be loaded from disk.8 The BASIC program MUTO ATTACK will be loaded from the disk into memory. For example to load a pro gram from disk.8.The 1541 Disk Drive 355 that block has been used. type: LOAD "MUTO ATTACK".1 will load the file into the area of memory from which it was saved. The BAM is updated every time a pro gram is saved or when a data file is closed so that the DOS has available an up to date picture of the storage space left on the disko Loading and SavingPrograms The most obvious and immediate use of the 1541 drive is as a means of storing programs. by adding a secondary address of 1 to the LOAD command: LOAD "TANK BATTLE". To save a BASIC program on disk: SAVE "KILLER DAISIES". except that you must specify the disk drive as the device you wish to use by adding the device number 8 to a command. .

8 These operations will occur much more rapidly than with the cassette unit. For example to save a machine code program stored from $COOO to $CIOO. it is possible to prevent overwriting of data. The small notch in one edge of the disk is called a write protect noteh.356 The Commodore 64 Omnibus .0 followed by: SAVE "MACHINE CODE". and to . To use SAVE to save data from another area of memory. the SA VE command stores the contents of memory between the addresses pointed to by the contents ofthese locations. Because of the random access nature of disk drives. The locations concerned are: 43 Low byte of start address of BASIC pro gram 44 High byte of start address of BASIC pro gram 45 Low byte of start ofBASIC variables 46 High byte of start ofBASIC variables In normal use.192:POKE 43.193:POKE 45. so to save machine code pro grams wi thou t a monitor or assembler involves modifying the zero page locations used to mark the beginning and end of a BASIC pro gram in memory.Part 2 SA VE always saves a BASIC program. these two pointers must be loaded with the start and end address of that area. you would type: POKE 44. several pro grams can be stored on the same disk wi thou t increasing the time taken to load a pro gram.0 POKE 46. As with cassettes.

15 INPUT#15. As the name suggests these commands allow you to maintain the state of the disk by renaming files.B$.C$.D$ PRINT "ERROR CODE "A$ PRINT "ERROR TYPE "B$ PRINT" TRACK "C$ PRINT" SECTOR "D$ . Remember to CLOSE the channel after using i t.A$. For example: OPEN 15. To use these commands you must OPEN a channel to channel15 of the disk drive (use the secondary address 15). error is indicated by the red LED flashivg on the front ofthe drive. and is useful for more than storage of pro grams.8. 15 The commands are then sent to the disk drive using the PRINT# command. deleting files etc. DISK HOUSEKEEPING OPERATIONS The DOS recognises a group of commands known as housekeeping commands.The 1541 Disk Drive 357 prevent overwriting this must be covered with one ofthe small sticky tabs supplied with the disko The disk drive is a very flexible device. The first of the commands is a method of reading the error status of the drive . The following program reads the error status of the drive from channel15: 10 20 30 40 50 60 OPEN 15. To exploit it fully you'll need to know more about how it works.

and its format is: PRINT#15.The Commodore 64 Omnibus ."V" Scratch You can delete files from the disk with the SCRATCH (abbreviated to S) command .Part 2 358 A list of DOS errors and their meanings is given in Appendix 6. This is a very cumbersome way of obtaining error information. Initialise The INITIALISE command (abbreviated to I) returns the disk drive to its normal state by copying the BAM into disk drive RAM. All files are c10sed and error conditions cancelled."I" You will find this command useful when experimenting with some ofthe more complex disk operations in the next chapter! Validate A VALIDATE operation will 'tidy up' and force the DOS to re-organise the files on the disk and thus make optimum use of the available disk space and free any partially used blocks."S:FILE NAME" . The command is abbreviated to V. and a more convenient method is described in the section on the DOS support program on page 150. The syntax IS: PRINT#15.the formatis: PRINT#15.

"R:NEW ENTRY=OLD ENTRY" THEDOSSUPPORTPROGRAM One of the pro grams on the demonstration disk supplied with the 1541 disk drive is a short machine code pro gram which supports the DOS resident in the disk drive.this technique is discussed in the section on sequential files in the next chapter."C:NEW NAME=OLD NAME" Another function of the COPY command is to combine files .1". Copy The COPY (C) command allows you to duplicate a file under a different name on the disko The syntax lS: PRINT#15.The 1541 Disk Drive 359 y ou can delete a group of files using the 'wild card' facili ty. its function is to simplify disk handling commands. Known as "DOS 5."S:TEST*" would delete all files on the disk whose file names began with the characters TEST. which is . The machine code is loaded into the 64 by a short BASIC program called "C-64 WEDGE". or you may delete files you want to keep. Be careful when using this facility. for example: PRINT#15. Rename It is possible to alter the directory entry for a file using the RENAME (R) command: PRINT#15.

DOS 5. and use the space bar to stop and start the scrolling. Directory For example to obtain a directory of a disk.1 allows you to search the directory for a specific pro gram as follows: @$ PROGRAM NAME If the program is on the disk its name will appear on the screen. Under DOS 5.1 is located in the 4k block of memory from $COOO i t has no effect on the amoun t of memory available for BASIC programs. Y ou can slow down the scrolling of a long directory by holding down the CTRL key.The Commodore 64 Omnibus . Y ou can search for and display the names of pro grams in a specified group by adding an asterisk (*) to the program name: @$ PROG* . Since DOS 5. use the command: @$ The directory will be loaded direct1y in to screen memory and not as a program.Part 2 360 also on the disko This simply loads DOS 5.1 the @ and > keys are used to issue commands to the disk drive. in exact1y the same way as PRINT# is used to issue commands via channel15.1 and initialises it with a SYS call to its start address. otherwise the directory will appear blank. so any program in memory will not be overwri tten.

the status can be read by typing: @ (or » without the need to run a program. type: /PROGRAM NAME . TI. regardless of the preceding four characters. and the track and sector on which the error occurred. This will result in a display of the error code and type (as given in Appendix 6). Error Status When a disk error is indicated by the flashing red LED. Similarly the command @$ ????NAME will search for and display the names of any programs whose last four characters are NAME.1.The 1541 Disk Drive 361 This will display the names of any programs in the directory beginning with the characters PROG. SS where XX is the error code number TI is the track number SS is the sector number Loading BASIC Pro grams To load a BASIC program under DOS 5. ERROR MESSAGE. in the following format: XX.

by typing: i PROGRAM NAME Saving BASIC Pro grams You can save a BASIC pro gram by typing: ~ PROGRAM NAME All the other operations described earlier in this chapter which involve issuing commands to the disk drive via channel 15 can be duplicated with the @ or > keys.1 and loads the machine code pro gram or data into memory. Loading Machine Code Programs To load a machine code program.The Commodore 64 Omnibus . Again DOS 5. For example. rather than at 2048 as with a normal LOAD or / command. type: %MACH PROG and press RETURN. This has the same effect as the statement: LOAD "MACH PROG". Quotation marks are optional.8. type: .1 does not require quotation marks around the program name. Auto Loading BASIC Pro grams DOS 5.Part 2 362 and press RETURN.1 allows you to load a BASIC pro gram so that it will run automatically. to format a disk. starting at the location from which it was saved.

1 make s the life ofthe 1541 disk user much easier .20 7:PO KE 45.20 4:PO KE 43.The 1541 Disk Drive 363 @N:DISK NAME.ID Quitt ing DOS 5. To do this first load DOS 5. and it can be reacti vated by typin g: SYS 52224 DOS 5.1" .1 into the 64 from the demo nstrat ion disk.0 POKE 46.the techn ique is descr ibed earlie r in this chapt er. To reset the point ers afterw ards type: NEW .1" was a BASI C progr am . then type: POKE 44.1 If you want to stop using DOS 5. it can be deactiva ted with the comm and: @Q This will retur n the 64 to its norm al state. but it's not very conve nient to have to load it into the comp uter from the demo nstra tion disk every time you use the mach ine.1 from memo ry.8 The mach ine code will be saved on your disk for your future use. It is a good idea to copy it onto your own disks. but will not delete DOS 5.89 Now inser t your disk and type: SAVE "DOS 5. becau se the four POK Es 'trick ed' the 64 into think ing "DOS 5.1.

CHAPTER 25 ADVANCED DISK OPERATIONS The disk drive is useful for more than program storage and this chapter covers the various types of data file available with the 1541 drive. This method of data storage is acceptable for small amounts of data. disk sequential files are created with the OPEN command. but this has the limitation that to access any item of data on a tape.SA. but only a very keen enthusiast could make much serious use of such an arrangement for an application such as a database.Dev. LFn. The syntax of the OPEN statement when creating a sequential file is: OPEN LFn. a cassette unit can be used for storage."NAME. and the commands needed to make use of them. SEQUENTIAL DATA FILES Most applications for computers require some means of storing and retrieving data. In a simple system. one byte after another. but are much faster in use.the data is stored sequentially. As with cassettes. can be any number between 0 and 255.S.Type" The logical file number. A section on the use of machine code with the disk drive is included. Sequential files can also be stored on floppy disks in exactly the same way as with cassettes. the computer must first read through all those that precede it . along the tape. and is used to reference that file .

will result in an error. When the OPEN command is executed. If no type parameter is included. as specified by the type parameter. and the character 'S' indicates a sequential file. A device number. and the Secondary Address. and free the channel for other uses. a new file is created. Any other use of OPEN. Dev. Filenames may contain up to sixteen characters. This will complete the transfer of data from the buffer onto the disk. The rules are exactly the same as those for printing to the screen and with cassette files and need not be covered here. Reading and Writing Sequential Files The PRINT# command is used to write data to a sequential file. The type parameter specifies whether the file is to be read (R) or written (W). of 8 specifies the disk drive. If the file is not . Data items can be separated by carriage returns (CHR$(13)). Closing Sequential Files A file must be closed after use. may be any number between 2 and 14. a new file is created ready for a write operation. the DOS checks to see if the file already exists and if so the file is opened ready for a read or write operation. If the file doesn't exist and a write operation is specified.Advanced Disk Operations 365 throughout the program. SA. The GET# and INPUT# commands are used to read data from a sequential file and again their use is exactly the same as with cassette files. such as trying to open a non-existent file for a read operation. commas or semicolons.

CHR$(65+X)."SEQUENTIAL FILE. some data may be lost."SEQUENTIAL FILE.6. NEXT X CLOSE 6 REM READ IT BACK! OPEN 6. with the COPY command.8.A$ PRINT A$.8."@:UPDATED FILE.W" Concatenating Sequential Files You can add the contents of up to four sequential files together making one large file. For example the following statement would add the contents of the file called STOCK to the file called PRICES and create a new file called . and how data can be written to and read from i t: 1 10 20 30 40 50 99 100 110 120 130 140 150 REM SEQUENTIAL DEMO OPEN 6.S.S. W":REM OPEN SEQUENTIAL FILE FOR A WRITE OPERATION FOR X=O TO 25:REM WRITE DATA PRINT#6.8.S.10. R":REM OPEN FOR A READ OPERATION FOR X=O TO 25 INPUT#6.Part 2 366 elosed.6. NEXT X CLOSE 6 You can re-open a sequential file to enable it to be updated by inserting a @ symbol in the command like this: OPEN 3.The Commodore 64 Omnibus . The command to elose a file is: CLOSE LFn The next program shows how to create a sequential file on a disk.

seque ntial files make very effici ent use of the disk space . Becau se data is store d one item after anoth er. IIC:INVENTORY=O:STOCK. . The DOS keeps areco rd of the track s and sector s used by a relati ve file by estab lishin g side sectors . at the expen se of less effici ent use of disk space and more comp lex progr ammi ng. The word proce ssor progr am which we used to write this book stores its text as a seque ntial file. and its use result s in a large time adva ntage over sequ entia l files. but are inflex ible when it come s to more sophi sticat ed applic ations .the arran geme nt is show n in the table on the next page. there by simpl ifying the progr ammi ng task. in which no single item of data is to be retrie ved alone . This proce dure is hand led comp letely by the DOS . Each re cord in a relati ve file may conta in up to 254 chara cters .a list of point ers to the start of each recor d withi n a relati ve file. PRIN T#15. There is anoth er type of data file you can use with the 1541 drive which overc omes some of the limita tions of seque ntial files and allow s you to access data from any point on the disk witho ut havin g to read all that prece des it. RELATIVE DATA FILES Relat ive files allow the progr amme r ready access to any item of data on the disk by struc turing the data into re cords. O:PRICES II Seque ntial files are usefu l for storin g such thing s as chara cter sets or sprite data. This is know n as the relative file.Advan ced Oisk Opera tions 367 INVE NTO RY whic h woul d conta in aB the inform ation.

9 Track & sector of side sector number 2 10. 1 Pointer to T & S of next side sector block 2 Side sector Number 3 Record Length 4.Part 2 BYTE CONTENTS Poi nter to T & S of next data block 0.1 254 bytes of data. BYTE CONTENTS 0. 2-255 Relative File Data Block Format Each side sector is contained in a single data block and can store pointers. Partially filled records are padded with nulls. containing the data given in the table above. Empty records have FF as first character. in the form of track and sector numbers. for up to 120 records. 15 Track & sector of side sector number 5 16-255 Track & sector pointers to 120 data blocks Relative File Side Sector Block Format Each relative file can have up to 6 side sectors. a side sector is created for that file.13 Track & sector of side sector number 4 14.368 The Commodore 64 Omnibus . and so may comprise up to 720 records . 11 Track & sector of side sector number 3 12. all the rest are null.5 Track & sector of side sector number 0 6. and the first record of that file is .more than the capaci ty of a disk! Creating a Relative File When a relative file is created. 7 Track & sector of side sector number 1 8.

INAME."+ CHR$ (Rec.Chan."PICHR$(C)CHR$(Low)CHR$(High) Where C is a ehannel number and Low and High are the low and high bytes of the reeord number (two bytes are needed beeause a reeord number may be greater than 255). Like other DOS eommands. having reeords whieh are 50 characters long. The BASIC OPEN command is used to create a relative file: OPEN LFn."+CHR$(SO) where file number 2 has been used to create a relative file called DATABASE.2. It is quite in order . rather a warning that no INPUT# or GET# operation should be attempted.IDATABASE. Onee a file has been created it ean be aeeessed in the usual way.L. the number of the required reeord must be specified using the POSITION eommand.IDATABASE" Reading and Writing Relative Files To read or write data in a relative file.Advanced Disk Operations 369 set up. the error code 50 is ereated.L. If you position the pointer to a reeord whieh hasn't been ereated. whieh should not be regarded as an error. without specifying file type: OPEN 2. POSITION (abbreviated as P) is se nt to the drive via ehannel15: PRINT#lS.2.8. The POSITION eommand positions the file pointer to the specified reeord before a read or wri te operation.Length) An example of this command in use is: OPEN 2.Dev.8.

A check of the error channel gi ves the error message ERROR 50 .The Commodore 64 Omnibus .D PRINT "ERROR"A.RECORD NOT PRESENT. Each record so created will contain 255 as the first character. this is interpreted as a warning not to read data. all subsequent operations with the relative file will be greatly speeded up.8.using PRINT# after setting the file pointer to the required position. but as explained above."THIS IS THE 100TH RECORD" CLOSE 15:CLOSE 2 END How the Pro gram Works The program creates a relative file with arecord length of 100 characters. and any extra side sectors as required. it is advisable to create the last record at the start of the program. since the act of writing will create the record.2.B$ PRINT#2. The use of the POSITION command with relative files is ill ustrated in the following pro gram: 10 20 30 40 50 60 70 80 OPEN 15.A.8. and uses the POSITION command to place the file pointer at record 100. Data is written to a relative file in the same way as to a sequential file . Ifit is envisaged that a large number ofrecords are to be created."P"CHR$(2)CHR$(100) CHR$(O) INPUT#15. Line 60 ignores the error and .Part 2 370 to ignore the message if you intend to write data into the record."RELATIVE TEST. By creating these records.15 OPEN 2. This will force the DOS to create a11 the intermediate records.C.B$. indicating that is unused."+CHR$(100) PRINT#15.L.

2.8. This occurs because each empty record contains a CHR$(255) followed by 99 bytes of CHR$(O) and no terminator character.the ability to place the file pointer at any position within arecord.15 OPEN 2. 99 100 110 120 130 140 150 REM READ IN 100 TH RECORD OPEN 15.IIRELATIVE TEST II PRINT#15. by using POSITION to move the file pointer to record 100 and read the con ten ts.8.Advanced Disk Operations 371 writes some data into re cord 100. This also causes records 1 to 99 to be created with 255 as the first character. The 80 character limit on the BASIC INPUT# command is therefore exceeded and an error occurs.IIP II CHR$(2)CHR$(100) CHR$(O) INPUT#2. a further facility of the POSITION command is used . The next frogram will allow you to read the contents 0 the relative file just created. You can overcome this problem by using GET# to check that the first character of arecord isn't 255 before reading the contents of that record. To do this.D$ PRINT IITHE CONTENTS OF RECORD 100 ARE: IID$ CLOSEI5:CLOSE2 If you modify the program to read any other record. a 'STRING TOO LONG' error will be generated when the program attempts to read the data. like a carriage return or comma. This is achieved by adding a further parameter to the P command specifying the posi tion wi thin arecord: . and the two channels are closed in line 70.

Part 2 372 PRINT#15."P"CHR$(2)CHR$(15)CHR$(0)CHR$ (10) This command would place the file pointer at the 10th byte of record 15 in the relative file accessed via channel2. . The example given in the 1541 manual of a mailing list shows the principles behind the technique (obvious errors aside!). Ifyou try record 100. so you will get peculiar results! To prevent this occuring in more serious applications you must reset the file pointer after checking . If you change the following lines in the last program. allowing more efficient use of the disk space and leading to a more flexible way of creating databases.T$:IF T$=CHR$(255) THEN PRINT "EMPTY RECORD":GOTO 150 If you run the modified program using any re cord number between 0 and 99 you will discover empty records."P"CHR$(2)CHR$(R) CHR$(O)CHR$(O) GET#2. The ability to position the file pointer to any point within arecord means that arecord can be divided into fields.The Commodore 64 Omnibus . The program later in this chapter is a more comprehensive example of the use of relative files together with indexing sequential files.R PRINT#15. you will be able to use this technique to test each record in the file: 115 120 125 INPUT"WHICH RECORD". the DOS will become confused about the contents of the record because the GET# in line 125 has moved several bytes of data into the buffer.for an empty re cord if you then want to use INPUT#. To make it work. you must keep track of the length of each field in order to be able to read and write into each field.

To use rando m files two chann els must be opene d to the disk drive . They are harde r to progr am than relati ve files and offer no advan tage over them in most applic ations . and the only reaso n for choos ing a specific one is for mach ine code applic ations where some code is to be stored in the buffe r." #" An exam ple ofits use is: OPEN 5. Chan nel NO. but this is not norm ally neces sary. Open ing a Rand om File The synta x of the OPEN comm and for a rando m file is show n below: OPEN LFn. Read ing and Writi ng Rand om Files Havin g 0 PENe d a rando m file. anoth er comm and is sent via chann el15 to instru ct the DOS to eithe r read the conte nts of a specified track and secto r . Dev.8.Advan ced Disk Opera tions 373 RAN DOM DATA FILES Rand om data files provid e a me ans of specif ying the track and sector of the disk upon which your data is stored .5 . They do offer great er contr ol over what goes where on the disk. but are less effici ent in their use of disk space than relati ve files. and you need to know at what addre ss it starts . one for sendi ng comm ands (chan nel 15) and anoth er for sendi ng data to one of the 256 byte RAM buffe rs in the disk drive. The DOS selec ts the next avail able buffe r for you."#" The # symb ol can optio nally be follow ed by a numb er to specify in which of the buffe rs you want to store the data.

BLOCK-READ The syntax ofthe BLOCK-READ command is: PRINT#15. The following program demonstrates the use of the BLOCK-READ command to display the contents of any track and sector .0.Tk.5.8.S IF(T>18 AND S>20)OR (T<25 AND S>18)OR(T<31 AND S>17)OR(T<36 AND S>17) THEN 30 PRINT#15.T. or to write the contents of the buffer to a specified track and sector of the disko The two commands which do this are BLOCKREAD and BLOCK-WRITE (abbreviated as B-R andB-W)."B-R:"Chan.Sec Note that the parameters are separated by semicolons (.8.Part 2 374 into the selected buffer.) and not commas as described in some versions of the 1541 disk drive manual."B-R:"5.D$ IF ST=O THEN A$=A$+D$:NEXT Z PRINT "{CLS}TRACK "T" SECTOR" S:PRINT PRINT A$ CLOSE 5:CLOSE 15:END .The Commodore 64 Omnibus ."#" PRINT"{CLS}": INPUT "WHICH TRACK. 5 10 20 30 40 50 60 70 80 90 100 110 REM BLOCK READ DEMO OPEN 15.Drv. The drive number.S FOR Z=O TO 255 GET#5.SECTOR?". is 0 for a single drive unit like the 1541 and can be omitted.Drv.T.15 OPEN 5.

The loop in lines 60 to 80 contin ues to read data one byte at at time from the buffe r for as long as the system statu s word. anoth er input is reque sted. which displ ays the conte nts oftrac k T."B-W :"Cha n. and the drive numb er is zero for a single drive. sector S.Advan ced Disk Opera tions 375 This progr am will work for any block.S ec Again the param eters are separ ated by semicolons. BLOC K-WR ITE The BLOC K . How the Prog ram Work s Lines 10 and 20 open chann el15 for comm ands and chann el 5 to the buffe r. drive 0 and the track and secto r numb ers which specify the data block to be read. try using it to exam ine the direct ory (track 18 sector 1).Tk.WRIT E comm and perfo rms the opposite action to the B-R comm and and allow s you to write data to any block on the disko Its synta x is: PRIN T#15 .Drv . Line 50 sends the Block Read (B-R) comm and. . but to see some thing mean ingfu l. ST. is zero. When the end of the data in the block is reach ed ST is set to 64 and contr ol jump s to line 90. Line 30 sets the varia bles T and S to the chose n track and secto r and line 40 check s that such a comb inatio n of track and sector exists on the disko Ifnot . specif ying the buffe r assoc iated with chann el 5.

0.8. The byte returned is the number of the buffer selected by the DOS. You can probably imagine that writing data haphazardly all over the disk in this way isn't very useful .5. sector 1 of the disk .CHR$(1+65) NEXT 1 PR1NT#15. . You can only interrogate the disk drive for buffer information before any read or write operations are carried out with that buffer. This is perfectly acceptable under normal circumstances. and to update the BAM after writing the data.R pro gram above.Part 2 376 The following program wri tes the letters of the alphabet onto track 1. care must be taken to check the BAM for a free block before writing data to the could check this by using the B. 10 20 30 40 50 60 70 OPEN 15. In these examples.The Commodore 64 Omnibus .15 OPEN 5.1 CLOSE 15:CLOSE 5 Notice that the data is written into the buffer via channel 5. we have not specified which buffer is to be used for B-R and B-W can easily lose track of what data is where and if you inadvertently overwrite another file or the directory you can ruin the disko For random files to co-exist safely with program and other files on a disk. You can find out by issuing a GET# command immediately after opening the channel for data (in our case channeI5). leaving the choice up to the DOS.1. but in very complex pro grams you may want to know which buffer has been selected for a particular operation.8."B-W:"5. and when this operation is complete the contents of the buffer are written to the block specified in the B-W command."#" FOR 1=0 TO 25 PR1NT#5.

Line 30 attem pts to alloca te this block.Advan ced Disk Opera tions 377 The comm and which allow s you to do this is BLOC K-AL LOCA TE.8 .C. The next pro gram show s B-A in opera tion. Ifit isn't. 10 20 30 40 50 60 70 80 PR1NT "{CL S}": OPEN 15. along with the numb ers of the next availa ble track and sector. the DOS will check the BAM to see iftha t block is availa ble."B-A:"0~T~S 1NPU T#15 . and line 40 reads the result s of the attem pt from chann el15. and conse quent ly not availa ble.Tk. as in this exam ple.15 T=18 :S=1 PR1NT#15. If.S ec If you precede an attem pt to select a block for use in a rando m file by a B-A comm and. BLOC K-AL LOCA TE The synta x of BLOC K-AL LOCA TE (abbr eviate d asB-A ) is: PR1N T#15 . its entry in the BAM is set to 1) then an error code of 65 is retur ned and the numb ers of the next availa ble track and sector are . the DOS finds that the requ ested block is unava ilable (i."B-A :"Drv .A.B$ . an error is return ed via chann el 15.D 1F A<>65 THEN 80 PR1NT "TRACK"T" SECTOR"S" 1S NOT AVA1LABLE": PR1NT PR1NT "THE NEXT FREE BLOCK 1S AT TRACK "C: PR1NT TAB( 26) "SECTOR"D:END PR1NT "TRACK"T" SECTOR"S" MAY BE USED" How the Pro gram Work s The track and sector for alloca tion are set to 18 and 1 whic h is the start of the direc tory.e.

5. Each random file would have a corresponding sequential file containing information about which blocks have been used. The results of the B-A attempt are displayed by lines 60 to 80.8. BLOCK-FREE BLOCK FREE (B-F) is a corresponding command which allows you to release a block for use.Part 2 supplied.N PRINT#4.378 The Commodore 64 Omnibus .8. this test would be carried out before any attempt to write data.4. No data is destroyed but the BAM entry for the specified block is cleared allowing new data to overwrite what is already there.S. In practice.Tk.8. the B-A command updates the BAM and a write operation can be performed."B-F:"Drv.N FOR X=l TO N PRINT"{CLS}ENTER DA TA FOR ENTRY NUMBER".X ."@0:INDEX.15 OPEN 5. 10 20 30 40 50 55 60 70 T=l:S=l OPEN 15. The following short program stores data in a random file and keeps an index of the track and sectors as they are used. If the block is available. The best way of doing this is by maintaining a 'directory' in a sequential file. you need to keep a record ofthe blocks allocated to a random file. The syntax of the B-F command is: PRINT#15."#" OPEN 4.Sec To make use of random files.W" INPUT"NUMBER OF ENTRIES".

S .4.N INPUT "WHICH RECORD TO RETRIEVE"iNR IF NR>N THEN PRINT"NO SUCH RECORD l":GOTO 240 FOR X=l TO NR INPUT#4."S NEXT X PRINT"BYEll" CLOSE 4:CLOSE 5:CLOSE 15 END How the Program Works Lines 20 to 40 open the three channels."B-A:"OiTiS INPUT#15. This number is stored as the first character in the sequential file "INDEX".T". allocates a block with the B-A command.C. and using the B-R command to access i t.8.T. and line 50 inputs the number of entries to be made to the file.Advanced Disk Operations 80 90 100 110 120 125 130 140 150 160 170 379 INPUT D$ PRINT#5.D$ PRINT#15.A.S.8. channel 4 being used for the sequential file which scratches any previous file called "INDEX".B$."B-W:"5iOiTiS PRINT#4. The loop in lines 60 to 140 inputs file data from the keyboard.D IF A=65 THEN T=C:S=D:GOTO 100 PRINT#15."#" OPEN 4.8.R" INPUT#4."INDEX.15 OPEN 5. writes the data to the block and adds the track and sector number of the block to the sequential file. This is demonstrated in the next program: 200 210 220 230 240 250 260 270 OPEN 15. Reading data back from such random files involves using the data in the sequential file to find the track and sector at which any data item is located.5.

The Commodore 64 Omnibus ."B-P:"Chan. You can use the buffer pointer to divide blocks into fields and so make more efficient use of the disk space.0.A$ PRINT A$ CLOSE 4:CLOSE 5:CLOSE 15 END If you run these two programs.T."B-R:"5. and then examine the directory of the is kown as the buffer pointer. Each time you create a random file data block. The Buffer Pointer One drawback of the technique in the pro grams above is that it is inefficient . but that the number of blocks free is reduced by the number of entries you specified in the first program.S INPUT#5. You can increase the efficiency of the method by storing more than one data item in a block.Position . (abbreviated as B-P). the DOS keeps a count of the number of characters written to the buffer during a random file operation . The buffer pointer can be set to any position within a block with the BUFFER-POINTER command . the buffer pointer is stored on the disk with the data. you'll see that there is no directory entry for the random file. To make this possible. After you have experimented you can free the blocks taken up by the random files using the VALIDATE command.Part 2 380 280 290 300 310 330 340 NEXT X PRINT#15. its syntax is: entire block would be used to store only one character.

TEN How the Program Works Three channels are opened to the disk and the loop between lines 40 and 70 creates each field of the record in the buffer. the buffer pointer being incremented by 20 for each item in line 50. FIVE.5.ONE.THREE.D$".8.NINE.FOUR. The next program allows you to inspect the random file just created."P NEXT P T=l:S=l PRINT#15. When all eleven data items are in the buffer in positions specified by line 50.SIX.W" FOR P=l TO 220 STEP 20 READ D$ PRINT#15.Advanced Disk Operations 381 This program shows how you can use the ß-P command to subdivide a block into fields.T". the track and sector recorded in the indexing sequential file and the data written to the disk by line 130.15 OPEN 5.C."#" OPEN 4."B-P INDEX.D IF A=65 THEN T=C:S=D:GOTO 90 PRINT#4."B-A:"OiTiS INPUT#15.EIGHT. 1 10 20 30 40 45 50 60 70 80 90 100 110 120 130 140 150 160 REM B-P WRITE PRINT"{CLS}":OPEN 15.TWO.4.A."S PRINT#15.8."B-P:"5iP PRINT#5.SEVEN.S.8. 1 10 REM B-P READ DEMO PRINT"{CLS}" .B$. a disk block is allocated in the usual way."B-W:"5iOiTiS CLOSE4:CLOSE5:CLOSE15 END DATA ZERO. by using the buffer pointer to select a single data item from the buffer.

USER 1 and USER 2 (abbreviated as U1 or UA and U2 or UB) are two of a set of commands used in .BP INPUT#5.0. the track and sector of the block are read from the sequential file by line 80.S.N PRINT"{CLS}FIELD"R"CONTAINS"A$ PRINT "AND STARTS AT BYTE"N CLOSE4:CLOSE5:CLOSE15 END How the Pro gram Works The logic of the pro gram is the reverse of that in the B-P read example.382 The Commodore 64 Omnibus .8.T. The buffer pointer position is calculated from the entered field number. .Part 2 20 30 40 50 60 70 80 90 100 110 120 130 140 150 OPEN 15.A$.R" INPUT"FIELD TO VIEW (0-10)"."#" OPEN 4.4.8.IB-P:"5.15 OPEN 5.8.IB-R:"5.R IF R<O OR R>10 THEN 30 BP=R*20+1 INPUT#4.T.READ and BLOCKWRITE commands covered in this section. machine code applications which are discussed later in this chapter."B-P INDEX.5. and the buffer filled with the contents of that block by li ne 90. There are two further commands which are variations of the BLOCK . Called USER 1 and USER 2 these commands allow you to deal with the contents of a complete block regardless ofthe buffer pointer. The buffer pointer is set to the required data item by line 100 and the contents ofthe field read from the buffer by line 110.S PRINT#15.S PRINT#15.

B$."{RVS} HOME BASE {ROF}{CO}{CO}{CO}{CO}" PRINT TAB(9)"{RVS}I{ROF} CREATE NEW FILE{CO}" PRINT TAB(9)"{RVS}2{ROF} ENTER RECORO{CO}" PRINT TAB(9)"{RVS}3{ROF} SEARCH FOR RECORO{CO}" PRINT TAB(9)"{RVS}4{ROF} EXIT{CO}{CO}{CO}{CO}{CO}" PRINT L$ PRINT TAB(10). HOME BASE 1 2 3 4 5 6 7 8 9 10 20 40 50 60 70 80 100 110 120 130 135 140 150 199 200 210 220 REM ************* REM * * REM * HOME BASE * REM * * REM ************* REM REM REQUIRES 1541 OISK ORIVE REM PRINT"{CLS}" GOSUB 10000 GOSUB 240 PRINT TAB(13).4000.8.O$ CLOSE 15 .6000 GOTO 20 REM REAO ERROR CHANNEL OPEN 15.C$.A$."{OKGRY}ENTER CHOICE {RVS}I{ROF} TO {RVS}4{ROF}{GRN}". GET A$:IF A$="" THEN 120 IF A$<"I" OR A$>"4" THEN 120 M$=BK$:GOSUB 300 ON ASC(A$)-48 GOSUB 1000. combined with sequential files. 5000.15 INPUT#15.Advanced Disk Operations 383 The following pro gram is an example of the use of relative file handling techniques.

384 The Commodore 64 Omnibus .Part 2 230 239 240 250 260 270 299 300 310 320 330 349 350 360 993 994 995 996 997 998 999 1000 1010 1020 1030 1040 1050 1060 1080 RETURN REM CREATE SCREEN LAYOUT PRINT"{GRN}{CLS}{ROF}CHR$ (169){14 SPACES}CHR$(223) {RVS}{24 SPACES}" PRINT"{16 SPACES}{{RVS}{24 SPACES} {ROF} " i PRINTTAB(39)iCHR$(223) RETURN REM OISPLAY M$ ON STATUS LINE PRINT"{HOM}{ 23 * CO}"iSPC(( 40-LEN(M$»/2)iM$i"{GRN}":IF NB=l THEN 330 FOR N=l TO NU:PRINT"{CU}" i: NEXT N PRINT BK$"{CU}" NU=O:RETURN REM ORAW HORIZ LINE PRINT"{HOM}{21 * CO}"iL$i "{HOM}{CO}{CO}" RETURN REM REM ********************* REM * * REM * CREATE A NEW FILE * REM * * REM ********************* REM GOSUB 240 PRINT TAB(10)i"{RVS} CREATE A NEW FILE {ROF}{CO}{CO} {CO}{CO}" INPUT" FILE NAME «15 CHARS)"i FT$ IF LEN(FT$»14 THEN 1000 IF FT$ = "" THEN RETURN PRINT:PRINT:INPUT" HOW MANY FIELOS/RECORO «ll)"iNF IF NF=O OR NF>10 THEN PRINT"{CU}{CU}{CU}":GOTO 1050 FOR Z=l TO NF .

: INPU T FL(Z ) RL=R L+FL (Z) IF RL>254THEN RL=R L-FL( Z):M$ = "{REO}RECORO LENGTH EXCEEOEO": NU=1 2:GOS UB30 0:GOT 01110 NEXT Z GOSUB 240 PRINT "{HOM}{CO}{CR}{OKGRY} "FT$" {GRN }" PRINT TAB( 10).F L(Z) NEXT Z:GOSUB 350 {ROF}PRESS M$="{OKGRY} CONTINUE TO F} }Y{RO {RVS REJE CT": TO F} }N{RO {RVS 300 B :GOSU NU=5 GET YN$: IF YN$="" THEN 1230 IF YN$="N" THEN RETURN OPEN 2." {RVS } CREATE A NEW FILE{ ROF} {CO} {CO} {CO} {CO} " PRINT "ENTER NAME OF FIEL O"Z.W" PRIN T#4.4 .8. TAB( 25)."{ CO}{ CO}{ RVS} CREATE A NEW FILE {ROF}{CO} {CO}{CO}" #"TA B(6).8.TAB (6).F R PRIN T#4.FT$ +" ."+ CHR$ (RL) CLOSE 2 OPEN 4. PRIN T" TAB( 25).L.N $(Z)."L ENGT H{CO }" FOR Z=l TO NF PRIN TTAB (2).2 .S .Z .Advan ced Disk Opera tions 1090 1100 1105 1110 1120 1130 1140 1150 1160 1170 1180 1190 1200 1210 1220 1230 1240 1250 1255 1260 1270 1275 1280 1290 1300 1310 385 GOSUB 240:G OSUB 350:P RINT TAB( 10).N F PRIN T#4.F T$ FR=l PRIN T#4."@0 :INO EX.R L FOR Z=l TO NF . "NAME".: INPU T N$(Z ): PRIN T:PRI NT IF N$(Z )="" THEN RETURN PRINT"ENTER LENGTH OF FIEL O"Z.

S.R" GOSUB 200 IF B$="OK" THEN CLOSE 4:GOTO 4060 NU=5: M$="{RED}"+B$:GOSUB 300 :FOR Q=O TO 1000:NEXT Q CLOSE 4:RETURN OPEN 4.4.FT$.S.R": INPUT#"INDEX."INDEX."FL(Z)".N$(Z)".RL FOR Z=l TO NF INPUT#4.FL(Z):NEXT Z CLOSE 4 FOR Z=l TO NF:GOSUB 240:GOSUB 350 PRINT "{HOM}{CD}{CR}{DKGRY}" FT$"{GRN}" PRINT TAB(ll) i "{CD}{CD}{RVS}ENTER A RE CORD {ROF}{CD}{CD}{CD}{CD}" M$="MAX FIELD LENGTH ="+STR$ (FL(Z»:NU=16:GOSUB 300 PRINT N$(Z)i INPUT R$(Z) IF LEN(R$(Z»<FL(Z) THEN 4220 NB=l:M$="{RED}FIELD LENGTH EXCEEDED":GOSUB 300:NB=0 FOR T=O TO 400:NEXT T:GOTO 4110 NEXT Z .N$(Z)." NEXT Z CLOSE 4 RETURN REM REM ******************** REM * * REM * ENTER NEW RECORD * REM * * REM ******************** REM IF LEN(FT$)<>O THEN 4100 OPEN 4.Part 2 1320 1330 1340 1350 3993 3994 3995 3996 3997 3998 3999 4000 4010 4020 4030 4040 4050 4060 4070 4080 4090 4100 4110 4120 4130 4140 4150 4160 4170 4180 4220 PRINT#4.386 The Commodore 64 Omnibus .NF.FR.

S."FL(Z)".Advanced Disk Operations 4230 4240 4260 4270 4280 4290 4300 4310 4320 4330 4340 4350 4355 4360 4370 4380 4390 4400 4410 4420 4430 4440 4450 4460 4470 4480 4490 4500 4510 4993 4994 4995 4996 387 FOR Z=l TO NF:GOSUB 240:GOSUB 350 PRINT "{HOM}{CO}{CR}{OKGRY} "FT$" {GRN} " PRINT TAB(ll)." NEXT Z CLOSE 4 T$="":FOR Z=l TO NF:R$(Z)="": NEXT Z:RETURN REM REM ********************* REM * * REM * SEARCH FOR RECORO * .R$(Z) NEXT Z:FR=FR+1 CLOSE 2:CLOSE 15 OPEN FOR Z=l TO NF HI=INT(FRj256):LO=FR-HI*256 PO=PO+FL(Z-l) PRINT#15.FR PRINT#4.FT$ OPEN 15.N$(Z)".8."P"CHR$(2)CHR$(LO) CHR$(HI)CHR$(PO) PRINT#2.NF PRINT#4.4."@0:INOEX.RL FOR Z=l TO NF PRINT#4.8.FT$ PRINT#4.W" PRINT#4."{CO}{CO}{RVS} ENTER A RECORO {ROF}{CO}{CO} {CO}{CO}" FOR Z=l TO NF PRINT N$(Z)" "R$(Z) NEXT Z NB=l:M$="{OKGRY}PRESS {RVS}Y {ROF} TO ACCEPT {RVS}N{ROF} TO REJECT":GOSUB 300:NB=0 GET YN$:IF YN$="" THEN 4310 IF YN$="N" THEN 4510 IF YN$<>"Y" THEN 4310 OPEN 2.

RL FOR Z=l TO NF INPUT#4.FR.N$(Z) NEXT Z M$="tOKGRY} SELECT FIELO FOR SEARCH {RVS}A{ROF} TO "+ "{RVS}"+CHR$(NF+64)+"{ROF}" NB=l:GOSUB 300:NB=0 GET A$:IF A$="" THEN 5180 IF A$<"A" OR A$>CHR$(NF+64) THEN 5180 F=ASC(A$)-64:GOSUB 240:GOSUB 350:T$="" PRINT "{HOM}{CO}{CR}{OKGRY} "FT$"{GRN}" PRINT TAB(10).8."{CO}{CO}{RVS} SEARCH FOR RECORO {ROF}{CO} {CO}{CO}{CO}" FOR Z=l TO NF PRINT "{RVS}"CHR$(Z+64)"{ROF} ".8.N$(Z).S.The Commodore 64 Omnibus .NF.R": INPUT#4."{CO}{CO}{RVS} SEARCH FOR RECORO {ROF}{CO} {CO}{CO}{CO}" .FL(Z):NEXT Z CLOSE 4 GOSUB 240:GOSUB 350 PRINT "{HOM}{CO}{CR}{OKGRY} "FT$"{GRN}" PRINT TAB(10).Part 2 388 4997 4998 4999 5000 5010 5020 5030 5040 5050 5060 5070 5080 5090 5100 5110 5120 5130 5140 5150 5160 5170 5180 5185 5190 5200 5210 REM * * REM ********************* REM SE$="":Y=O:PO=O:IF LEN(FT$)<>O THEN 5100 OPEN 4.FT$."INOEX.4.S.4."INOEX.R" GOSUB 200 IF B$="OK" THEN CLOSE 4:GOTO 5060 NU=5: M$="{REO}"+B$:GOSUB 300 :FOR Q=O TO 1000:NEXT Q CLOSE 4:RETURN OPEN 4.

Advanced Disk Operations 5220 5225 5230 5260 5300 5310 5315 5320 5330 5350 5360 5399 5400 5405 5410 5415 5420 5430 5440 5499 5500 5505 5510 5511 5515 5520 389 M$=BK$:GOSUB 300: M$="{DKGRY} ENTER CONTENTS OF FIELD FOR SEARCH":NU=16:GOSUB 300 PRINT N$(F).T$ REM WILD CARD SEARCH IF RIGHT$(SE$.l)<>"*" THEN 5410 IF LEFT$(T$.2. INPUT SES M$=BK$:GOSUB 300:M$="SEARCHING FOR RECORD":NB=l:GOSUB 300: NB=O OPEN 2.FT$ OPEN 15.8.LEN(SE$)-l)=LEFT$ (SE$.15 FOR Q=OTOF-1:PO=PO+FL(Q): NEXT:PO=PO+1 FOR Z=l TO FR-1 HI=INT(Z/256):LO=Z-HI*256 PRINT#15.8." "."P"CHR$(2)CHR$(LO) CHR$(HI)CHR$(PO) INPUT#2."{CD}{CD}{RVS} SEARCH FOR RECORD {ROF}{CD} {CD}{CD}{CD}" F=FO(Z):HI=INT(F/256):LO=FHI*256 FOR Q=l TO NF .LEN(SE$)-l)THEN FO(Y)=Z: Y=Y+1:GOTO 5415 IF T$=SE$ THEN FO(Y)=Z:Y=Y+1 NEXT Z M$=BK$:GOSUB 300:M$=STR$(Y)+" RECORDS WERE FOUND":NB=l:GOSUB 300:NB=0 FOR T=O TO 500:NEXT T IF y=o THEN GOTO 5790 REM DISPLAY FOUND RECORDS FOR Z=O TO Y-1:PO=1 GOSUB 240:GOSUB 350 PRINT "{HOM}{CD}{CR}{DKGRY} "FT$"{GRN}" PRINTTAB(10).

CHR$(Q+64)"{ROF} "N$(Q)."P"CHR$(2)CHR$(LO) CHR$(HI)CHR$(PO):PRINT#2.R$(Q-1) PRINT BK$"{CR}{CU}{RVS}".R$(Q-1) NEXT Q IF Y=l THEN 5700 IF Z=Y-1 THEN Z=-l M$=BK$:GOSUB 300:NB=1: M$="{DKGRY} SHOW NEXT RECORD {RVS}Y{ROF} OR {RVS}N{ROF}?":GOSUB 300:NB=0 GET YN$:IF YN$="" THEN 5610 IF YN$="N" THEN AR=Z:Z=Yl:GOTO 5700 IF YN$<>"Y" THEN 5610 NEXT Z M$=BK$:GOSUB300:NB=1:M$= "{DKGRY} {RVS}A{ROF}MEND {RVS}DEL{ROF}ETE OR {RVS} RETURN{ROF}?":GOSUB 300:NB=0 GET YN$:IF YN$="" THEN 5710 IF YN$="A" THEN 5800 IF YN$=CHR$(13) THEN 5780 IF YN$<>CHR$(20) THEN 5710 M$=BK$:GOSUB300:M$="{DKGRY} {RVS} ARE YOU SURE? {ROF}" :NB=1:GOSUB300:NB=0 GET YN$:IF YN$="" THEN 5755 IF YN$<>"Y" THEN 5700 PO=l:FOR J=l TO NF:FOR K=l TO FL(J)-l:DE$=DE$+" u:NEXT K: PO=PO+FL(J-1) PRINT#15.390 The Commodore 64 Omnibus .Part 2 5530 5540 5550 5560 5565 5570 5580 5600 5610 5620 5630 5640 5700 5710 5720 5730 5740 5750 5755 5760 5770 5775 5780 5799 PO=PO+FL(Q-1) PRINT#15."P"CHR$(2)CHR$(LO) CHR$(HI)CHR$(PO) INPUT#2." ".DE$:D E$="":NEXT J Y=0:PO=0:CLOSE2:CLOSE15:RETURN REM AMEND RE CORD .

R$(Y}:NEXT Y:CLOSE2: CLOSE15 .SPC(2):R$(Q-1) M$=BK$:GOSUB 300:M$="MAX FIELO LENGTH ="+STR$(FL(Q)}:NB=l: GOSUB 300:NB=0 PRINT"{HOM}{10 * CO}"N$(Q}.R$(Y-1}: NEXT Y M$="{RVS}{OKGRY}Y{ROF} TO ACCEPT OR {RVS}N{ROF} TO REJECT":NB=l:GOSUB 300:NB=0 GET YN$:IF YN$="" THEN 5940 IF YN$="N" THEN RETURN IF YN$<>"Y" THEN 5940 PO=l:FOR y=o TO NF-1:PO=PO+ FL(Y} PRINT#15."P I CHR$(2}CHR$(LO} CHR$(HI}CHR$(PO} PRINT#2.:INPUT R$(Q-1} GOSUB 240:GOSUB 350 PRINT "{HOM}{CO}{CR}{OKGRY} "FT$"{GRN}" PRINT TAB(14}.Advanced Disk Operations 5800 5805 5810 5820 5830 5840 5845 5850 5860 5870 5880 5890 5900 5910 5920 5930 5940 5950 5960 5970 5980 5990 391 PRINT"{HOM}{CD}{CO}{CO}{CO} IBK$I{CR}{CU}"TAB(14} 11 {RVS}AME NO RECORO{ROF}" M$=BK$:GOSUB 300:M$="{OKGRY} {RVS}A{ROF}MEND WHICH FIELO?" :NB=l:GOSUB 300:NB=0 GET YN$:IF YN$="" THEN 5810 IF YN$<"A" OR YN$> CHR$(NF+64} THEN 5810 GOSUB 240:GOSUB 350:PRINT" {HOM}{CO}{CR} {OKGRY} "FT$" {GRN} " PRINT TAB(14}:"{CO}{CD}{RVS} AMEND RECORO {ROF}{CO}{CO}" Q=ASC(YN$)-64 PRINT N$(Q)."{CO}{CD}{RVS} AMENO RECORO {ROF}{CO}{CO}" FOR Y=l TO NF PRINT N$(Y}. SPC(2).SPC(1}.

remove the program disk from the drive and insert the file disko The database can extend over an entire diskette. formatted disko MainMenu The main menu comprises four options: 1 CREATE NEW FILE 2 ENTER ARECORD 3 SEARCHFORRECORD 4 EXIT At the foot of the screen is the status line .5:POKE 53281. insert a blank.392 The Commodore 64 Omnibus .this is used throughout the program to request inputs (dark grey text).Part 2 5995 6000 9993 9994 9995 9996 9997 9998 9999 10000 10010 RETURN PRINT"{CLS}BYEll":END REM REM ******************* REM * * REM * SET UP ROUTINES * REM * * REM ******************* REM POKE 53280. display error messages (red text) and give information about the current operation .15 FOR Z=O TO 39:L$=L$+CHR$(192): NEXT Z 10020 FOR Z=O TO 38:BK$=BK$+ CHR$ ( 32 ) : NEXT Z 10100 RETURN How to Use HOME BASE After loading the program. so it is best to reserve a disk for each file you wish to keep. If you want to create a new file.

the statu s line will displ ay the maxi mum numb er of chara cters allow ed in each field. If you accept. When the progr am is run the statu s line will prom pt for a choice from the main menu you will not be able to enter or searc h for areco rd until a file has been create d on the disko 1 Creat e New File The progr am will prom pt you to enter the name of the file and the numb er of fields it is to conta in. so that enter ing a numb er of chara cters followed by an asteri sk (*) will locate every record in which the specified field conta ins those chara cters. For each field you must enter a name and the maxi mum numb er of chara cters. the data is stored on the disk. and in both cases the main menu is redisp layed . 2 En ter aReco rd Each field in areco rd is filled in turn .Advan ced Disk Opera tions 393 (gree n text). After all the fields have been filled in this way the entire record is redisp layed . 3 Searc h For aReco rd The name s of the fields will be displa yed and you will be asked for the name and conte nts of the field to be used in the searc h. The disk will be searc hed for the specified field conte nts and ifmor e than one re cord . You can now enter data into the file. A 'wild card' facili ty is incor porat ed.the file name will be displa yed in the top left hand corne r of the screen . The total numb er of chara cters in a file may not exceed 254. If this numb er is exceeded an error messa ge will be displa yed and you will be asked to re-en ter the data. at which point you can reject it or accep t it. The file will be create d and contro l will retur n to the main menu .

The arrangement of data in the INDEX file is as follows: FT$ FR NF RL N$(1) FL(1) N$(2) FL(2) etc Name ofrelative file N umber of the next free re cord N umber of fields per record Length of arecord Name of field 1 Length offield 1 Name of field 2 Length of field 2 etc .ins information about the names and sizes of the fields in arecord. Amending aRecord The field to be amended is selected by reference letter and the new data entered. Deleting aRecord If you opt to delete arecord and press 'Y' in response to the ARE YOU SURE? prompt. you may display them all by responding 'Y' to the SHOW NEXT FIELD prompt. The amended record will be displayed for you to accept or reject.394 The Commodore 64 Omnibus . Pressing 'Y' will save the amended record and the main menu will be redisplayed. How the Program Works HOME BASE uses a single relative file to store data. length of arecord and the number of the next free record. or only one record was found. you will be given the option to amend or delete the re cord or return to the main menu. the re cord will be deleted and the main menu redisplayed.Part 2 is found. If you press 'N'. and a sequential file called INDEX which conta.

If the new record is accepted. F. reading the error channel. The disk is checked for the existence of an INDEX file if no file is currently loaded. the INDEX file is updated and the main menu redisplayed. an error message is generated and the main menu redisplayed. containing NF fields. If the comparison is successful the record number of that record is stored in array FO(). and data is read in from INDEX. is selected from them. and ifthe format is accepted.360 perform frequently used operations such as maintaining the status line. Lines 40 . are input and the appropriate field of each record on the disk is compared with SE$. Lines 1000 -1350 create a new relative file. A number ofsubroutines in lines 200 .150 display the main menu and input a selection from it. If no INDEX file is found on the disk. Lines 4000 .Advanced Disk Operations 395 INDEX is created at the start ofthe program when a relative file is set up. named FT$. The field names contained in array N$( ) are displayed and the field for the search. The name and length of each field is entered. a relative file having records of length RL is created. . SE$. it is stored on the disk at record FR. Lines 5000 . The contents of the field for the search. and the INDEX file set up. and updated each time a new record is added to the relative file. etc.4510 handle the entry ofa new record. If no file is currently loaded. the disk is checked and data from the INDEX file is loaded. The data for each field is entered and stored in array R$().6000 provide the search facility.

providing a twild card' search.5995 allow amendment of a field in the re cord and if the amendment is accepted. where amend and delete options are offered. rewrite the entire record to the disk and redisplay the main menu. by printing blank strings to the appropriate fields on the disko Lines 5800 .396 The Commodore 64 Omnibus . If only one record was found. If no records were found a message to this effect is displayed and the main menu is redisplayed. at which point control passes to line 5700. the re cord is displayed and control passes to line 5700. Varia ble U se FT$ NF N$() FL() RL L$ M$ BK$ FR File name N umber of fields/record Array of field names Array of field lengths Record length Horizontalline Message for status line Blankline Next free record number . If more than one record was found. At the end of the search. Lines 5750 . pressing ty' in response to the tSHOW NEXT RECORD' prompt will allow each record to be displayed in turn.5799 delete the displayed record. the number of re cords displayed is Y.Part 2 If the last character of SE$ is an asterisk (*) the comparison only covers the number of characters in SE$. continuing to cycle until tN' is pressed.

the record numb er of adele ted re cord would be alloca ted to the new record. The restri etion of 80 chara cters per field is due to the BASI C INPU T comm and and could be overcome using G ET and some form of check ing routin e. . When areco rd is delete d. it can not be re-use d and disk space is waste d. a numb er of funct ions are omi tted which would make i t much bette r for specific jobs.Advan ced Oisk Opera tions R$(l) 397 Conte nts offiel d I Impr ovem ents to the Prog ram In order to make this pro gram as gene rally applic able as possible (and to allow room for the other chapt ers in the book!). For exam ple. Addit ionall y. some form of hardc opy option migh t be usefu l. The progr am is desig ned for just one relati ve file per disk. the free forma t of the displa y could be repla ced by a fixed card form at to sui t your applic ation. but if you used yet anoth er seque ntial file as a direct ory there 's no reaso n why you shoul dn't keep more than one relati ve file per disko With the inform ation provi ded it would be a usefu l and instru ctive exerc ise to modif y and impro ve HOM E BASE to suit your requi remen ts. One way round this would be to keep anoth er seque ntial file of delete d recor d numb ers. When a new record is create d this would be check ed and if there are any entrie s.

Part 2 MACHINE CODE AND THE 1541 DRIVE The DOS recognises a group of commands designed to allow you to create machine code programs to run in the disk drive RAM. However the commands· are briefly covered here should you find need to use them. The format is: PRINT#15.information which is not freely available from the manufacturers.W allows you to send data comprising machine code programs from the 64.398 The Commodore 64 Omnibus . possibly modifying the operation ofthe DOS.T. BLOCK-EXECUTE (B-E) This command allows you to load machine code routines from the disk into disk drive RAM and execute them. into disk drive RAM. "M-W: "CHR$(Lo}CHR$(Hi}CHR$(N} CHR$(A}CHR$(B} •••• etc . It is similar to the B-R command except that after loading the code. MEMORY WRITE (M-W) M . The program must end in an RTS (ReTurn from Subroutine) instruction.S where a block of data is read from track T sector S on drive Dr into the channel eh buffer.Dr. via channel 15. and execution commences at byte 0 ofthat buffer."B-E:"Ch. To use these commands requires a detailed knowledge of the DOS pro gram and the architecture of the disk drive . the disk drive's microprocessor begins to execute it. The format ofthe command is: PRINT#15.

The Ul and U2 commands perform the B-R and BW operations mentioned earlier. which must be set up to contain the start address of the machine code pro grams you wish to execute. . The format is: PRINT#15.R command provides a means for reading data from disk drive ROM or RAM.Advanced Disk Operations 399 where a program consisting of bytes A. until an RTS is encountered. one byte at a time. The characters 1 to 9 or A to J can be used. but ignore the bufTer pointer to operat~ on an entire data block. MEMORY READ (M-R) The M . The remaining eight point to the locations given in the table opposite. + MEMORY EXECUTE (M-E) Allows you to execute machine code pro grams in the disk drive memory from the address specified. up to N characters is sent to RAM starting at address (256*Hi + Lo). B etc. via the error channel into the 64. Up to 34 bytes may be sent at a time. The format lS: PRINT#15. "M-R: "CHR$(Lo)CHR$(Hi) The contents of the location specified by 256*Hi Lo can be read from channel15 using GET#. The command is followed by an ASCII character which forms an index to the table."M-E:"CHR$(Lo)CHR$(Hi) USER(U) The USER command makes i t possible to link to machine code pro grams by using a jump table set up in disk drive memory.

"UN:"Ch. The 1540 Disk Drive It is possible to use the 1540 disk drive (designed for the VIC 20) with the 64 with one change.S USING OTH ER DISK DRIVES WITH TH E 64 . The screen must be turned ofT during the loading of a program wi th the command: POKE 53265. or UJ Power up Vector The USER Command Jump Table The fonnat of the USER command command is : PRINT#15.Part 2 USER OPERATION U1 or UA B-Rcommand U2 or UB B-Wcommand U3 or UC Jump to $0500 U40r UD Jump to $0503 U5 or UE Jump to $0506 U6 or UF Jump to $0509 U7 or UG Jump to $050C U8 or UH Jump to $050F U9 or UI Jump to $FFFA U.T. turn the screen back on wi th the command: .11 When the program is loaded.Dr.400 The Commodore 64 Omnibus .

rather than all 8 bits in a byte being transmitted at once. To do so will involve considerable expense. so be warned! IEEE Drives A major disadvantage ofthe 1541 drive is that data transfers between it and the 64 use aserial data bus. not only for a dual drive unit like the 8050. We have tried using two drives in this way for making backup disks. For this reason the 1541 is very slow by disk drive standards as most disk drives adopt the faster (and more expensive) parallel technique.Advanced Disk Operations 401 POKE 53265. you can use the 64 with some of Commodore's larger (and more expensive) drives. as in a parallel system. Another problem with it is that only a relatively small amount of data can be stored on a disk because ofthe way in which it is formatted. and were plagued with such problems. . but also for an interface adaptor to provide the 64 with the necessary IEEE (parallel) interface.27 Twin 1541 Drives Many disk based applications are greatly enhanced by having two disk drive units. it seems that some errors in the ROMs cause drives used in this way to ~hang up' at random intervals for no apparent reason. This means that data is transmitted one bit at a time. If you have an application which requires greater storage capacity or more rapid data retrieval. Although it is possible to link 1541 drives together and change their device number as described in the manual.

but is usually quite simple .provided. The loader is often written in machine code. and use your loader to load the blocks back from the disk when load the program from the tape. Where onee you would aeeept a long delay in loading.Part 2 Copying Tape Software to Disk A major headaehe in upgrading from tape to disk is that your eolleetion of programs is still on tape.402 The Commodore 64 Omnibus .using kernal routines . and need to transfer your software to disko In a few cases this is simply a matter of loading the program into the 64. You can then load each block of pro gram from the tape and save it to disk in the normal way. and saving it onto disko However most eommercial software is protected aginst copying . There are other ways of protecting software. The most straightforward way to transfer such a program to disk is to find out how many parts the program is saved in and write a short BASIC loader to do the job of the machine code program on the tape. that you don't seIl the results ofyour efforts! . you soon become spoiled by the speed of disk drives.unfortunately this means that it is also protected against legitimate copying! One of the most popular ways of protecting 64 tapes is to save a program in several blocks. of course. to protect against the casual pirate. and it can be quite satisfying to (crack' this sort of problem . and have a short loader program as the first program on the tape.

CHAPTER 26 THE MPS801 PRINTER A printer is a useful addition to any microcomputer system.both character and graphie information can be obtained. Each dot corresponds to one pin. moves the print head along the carriage and prints the next character. There are several different types of printer and many variations of each type are available for the Commodore 64. At the end of a line. The MPS801 printer (formerly the 1525)is the most popular choice for -the home user since i t is both cheap and versatile . The printer receives data from the 64 on the serial bus and its microprocessor interprets the data sorting prin ting characters from con tro 1 characters. the print head returns to the lefthand side and the paper is serolIed ready for the next line of data. How the Printer Works The MPS801 is a dot matrix printer which uses a set of small pins arranged in a matrix to strike the ribbon and make small dots on the paper. . For each printing character the processor causes the hammer to strike the appropriate pins to create the dot pattern for that character. providing program listings and hard copy oftext and graphics generated by the computer.

Using the Printer Like other peripherals. The channel is opened using the BASIC OPEN command: OPEN LFn. about which Httle can be done.Dn. communication between the printer and the 64 is achieved by opening a channel to the device. The printer will print the complete 64 character set and continue to do so until you switch off or move the switch away from the tT' position.The Commodore 64 Omnibus .SA where: LFn is the logical file number (any number from 0 to 255) which is used to reference the channel. Testing The MPS801 is provided wi th a test facili ty . Plug one end of the serial interface cable into the 64 and the other into the rear of the printer. problems may arise in addressing either device. This is due to a fault in the operating system. turn off the computer and printer.insert some paper and move the three position switch at the rear ofthe printer to tT'. . This normally requires you to switch off all peripherals. If you have a 1541 disk drive connect the disk drive to the 64 and the printer to the spare socket on the drive.Part 2 404 Connecting the Printer Before connecting the MPS801 to the 64. then switch them on again before they can be used. In cases where more than one peripheral is connected to the bus.

A secondary address of 7 selects upper and lower case printouts. characters are transmitted to the printer using the PRINT# command as in the following example: 10 20 30 40 50 60 70 OPEN 4.Z. i t defaults to O.The MPS801 Printer 405 Dn is the device number which is either 4 or 5 depending upon the position of the three position switch at the rear ofthe printer. if you change line 20 in the previous program to: 20 FOR Z=33 TO 112:PRINT CHR$(Z)j :NEXT Z . The carriage return can be suppressed by adding a semicolon at the end of the PRINT# command. If no secondary address is specified in the OPEN command. and upper case and graphics mode printouts.CHR$(Z+64) PRINT#4. SA is the secondary address. A comma moves the print head into the next 'column' before printing and a carriage return is issued at the end of each PRINT# command. which acts like the CBM and SHIFT keys on the 64 by toggling between upper and lower case mode. Once the channel is opened. So.4 FOR Z=l TO 26 PRINT Z. To select upper case and graphics mode the secondary address is set to O.CHR$(Z+64) NEXT Z CLOSE 4 END Notice that wh at is displayed on the screen is mimicked by the printer. and that data can be formatted on the printer in the same way as it can on the screen.

The Commodore 64 Omnibus . 40 and 50. After issuing the CMD command. This is the way to obtain pro gram listings: OPEN 4. As with PRINTing to the display. The CMD command transfers the output from the screen to the specified channel.4 eMD 4 LIST After a listing has been obtained.Part 2 406 and delete lines 30. Its syntax is: eMD LFn where the logical file number must be the same as the one specified in the OPEN command. returning output to the TV screen. Another way of obtaining copy on the printer is to use the CMD command. all data normally output to the 64's screen is directed to the printer. the TAB and SPC commands work on the printer. . the output from the 64 is still directed to the printer. and to return to normal you must type: PRINT# LFn eLOSE LFn This will elear any data remaining in the printer buffer and elose the channel. the full 80 column capability ofthe printer will be demonstrated.

The two fonts are the same as those selected on the 64 by holding down the SHIFT key and pressing the CBM key. "BIG BROTHER IS WATCHING YOU "N$"!!!" CLOSE 4 END PRINTING MODES The MPS801 operates in various printing modes selected by control characters in the data sent to the printer. CLOSE and CMD commands to output data to the printer under program control as this program shows: 10 20 30 40 50 60 70 REM PRINTING UNDER PROG CONTROL PRINT"{CLS}" INPUT"NAME "iN$ OPEN 4. PRINT#. The table below shows the print modes and the control characters used to select them.The MPS801 Printer 407 It is possible to use the OPEN. The following program illustrates the difference: 10 20 30 REM CRSR UP/CRSR DOWN FOR Z=65 TO 90 A$=A$+CHR$(Z) . Cursor U p and Cursor Down The characters 'cursor up' (CHR$(145» and 'cursor down' (CHR$(17» select which of the two 128 character sets is to be used for printing. The characters in the above table are sent to the printer in PRINT# commands and interpreted by the printer as control characters. The mode so selected will continue to be the printing mode until a further control character is detected by the printer.4 PRINT#4.

4:PRINT#4. Graphics Mode Graphics mode (CHR$(8» allows the printing of user defined characters.A$ CLOSE 4 OPEN 4.The Commodore 64 Omnibus .Part 2 408 CODE FUNCTlON 145 17 Cursor up mode Cursor down mode 8 Graphics mode 16 18 146 Tab print head 14 Double width mode 10 Une feed 13 27. .A$ CLOSE 4 END A secondary address of 7 must be specified in the OPEN command for cursor down mode to work.4. 16 Carriage return Specify dot address 26 Repeat graphicdata Reverse on Reverse off Printer Control Codes 40 50 60 70 80 90 100 NOTE: NEXT Z OPEN 4.7 PRINT#4.

409 The MPS801 Printer Characters are designed on a 6 by 7 grid like this: 1 2 4 8 16 32 64 User Defined Character Grid N otice that the grid is not the same as the one used for defining characters on the 64! Characters are created by placing dots on the grid where a dot should appear on the paper as in the diagram below: 2 4 8 16 32 64 18 34 104 104 34 18 (+ 128) A User Defined Character .

The data for the character is sent to the printer as a string.232.4 PRINT#4.CHR$(8)D$ NEXT R FOR R=6 TO 0 STEP -1 D$=CHR$«2tR)+128) PRINT#4.4 FOR N=O TO 30 FOR R=O TO 6 D$=CHR$«2tR)+128) PRINT#4.CHR$(8)A$ CLOSE 4 END DATA 146.CHR$(8)D$i NEXT R NEXT N CLOSE 4 Tab Print Head You can move the printer head under pro gram control to any position using CHR$(16). following a CHR$(8).162. The next program will print the character on the grid opposite: 10 20 30 40 50 60 70 80 90 100 REM USER DEFINED CHAR PROG FOR Z=O TO 5 READ D A$=A$+CHR$(D) NEXT Z OPEN 4. Add 128 to the result and repeat the operation for each ofthe columns.Part 2 410 To obtain the DA TA statement defining the character take one column of the grid at a time and add together the values of the rows in that column containing a dot. A two .146 You can use the graphics facility to draw patterns on the printer as demonstrated by this program: 10 20 30 40 50 60 70 80 90 100 110 120 OPEN 4.232.The Commodore 64 Omnibus .162.

CHR$(16)H$L$"POS"P$ NEXT CLOSE 4 Reverse On I Reverse Off Reverse text can be printed by preceding the text by CHR$(18).4 A$="REVERSED TEXT" FOR I=l TO LEN(A$} R=l-R IF R=O THEN R$=CHR$(146}:GOTO 70 R$=CHR$(18} PRINT#4. Turn off reverse text with CHR$(146).MID$(A$. 10 20 30 40 50 60 70 80 90 REM PRINT HEAD DEMO OPEN 4. precede the text with CHR$(14).R$.1}. 10 20 30 40 50 60 70 80 90 100 OPEN 4.I.4 FOR I=10 TO 70 STEP 5 P$=STR$(I) H$=MID$(P$. Double width characters have the same dot pattern as standard characters but being twice as wide.l) PRINT#4. only half as many will fit on a line. . The next pro gram shows this control character in use.2. NEXT I CLOSE 4 END Double Width Characters You can highlight important information by printing the text using double width characters.The MPS801 Printer 411 digit number following the CHR$(16) specifies the posi tion between 0 and 79.1) L$=RIGHT$(P$. To print double width characters.

CHR$(27) CHR$(16) allows you to select one ofthese positions to commence printing data.CHR$(27)CHR$(16)CHR$(1) CHR$(44) specifies dot address 1*256 + 44 = 300 and moves the print head to that position.4 PRlNT#4.CHR$(14)"OR 40 COLUMNS OF THlS SIZE" CLOSE 4:END Line Feeds and Carriage Returns You can control the printer to some extent by sending line feed characters (CHR$(10» and Carriage return characters (CHR$(13».CHR$(10) NEXT Z PRlNT#4.4 PRlNT#4. These will allow you to create blank lines in your printouts: 10 20 30 40 50 60 OPEN 4. . Since there are 480 possible positions the dot address is specified in two bytes which follow the CHR$(27)CHR$(16) like this: PRlNT#4.The Commodore 64 Omnibus . "LlNE 1" FOR z=o TO 9 PRlNT#4."80 COLUMNS OF TEXT THlS SIZE" PRlNT#4.Part 2 412 10 20 30 40 50 REM DOUBLE WlDTH CHARACTERS OPEN 4."LlNE 12" Specify Dot Address The span of the print head can be divided up into 480 columns each one dot wide.

CHR$(15) PRINT#4. but to cover the entire width of the paper would require two commands. SereenDump The printer manual contains a program to output the contents of a standard screen to the printer.TAB(29)CHR$(8)CHR$ (26)CHR$(114)CHR$(129) CLOSE 4:END With a different choice of character you could make the underlining more this example. You can use CHR$(26) to underline headings as the next program shows: 10 20 30 40 OPEN 4.TAB(30)"A CENTRED HEADING" PRINT#4. The following program shows how you might do this. Y ou could repeat for any number of times between 0 and 255. you would need to repeat a single vertica line many times. using each pin of the print head to create a verticalline character like this: I 10 20 30 OPEN 4.4:PRINT#4. For example.CHR$(8)CHR$(26)CHR$ (100)CHR$(255) CLOSE 4 The single character CHR$(255) is repeated at each dot address across the paper.4 PRINT#4. if you wanted to draw a thick line across the payer. for 100 times specified by CHR$(100) . but .The MPS801 Printer 413 Repeat Graphie Data CHR$(26) allows you to repeat a byte of data in graphics mode a specified number of times.

The last character in the block is CHR$(13) .4. A fuH listing of these is given in Appendix 11 and an explanation of .a carriage .CHR$(145) U sing the Printer with Machine Code There are occasions when you might need to control the printer from within a machine code program for example in a word processing package where you want to dump the contents of an area of memory on to the printer. them in Chapter 18. line 60000 must be changed to : 60000 OPEN 4. The following pro gram rectifies that omission and performs the same operation in rather less space.4:PRINT#4.7:PRINT#4.Part 2 414 it will not print reverse video characters.P$ P$="":NEXT A CLOSE 4:END In order to obtain hardcopy of screens containing upper and lower case characters.The Commodore 64 Omnibus . 60000 60010 60020 60040 60050 60060 60070 60080 60090 60100 60110 60120 OPEN 4. The followingFrogram will output the contents of a small block 0 memory to the printer.CHR$(15) FOR A=1024 TO 2023 STEP 40 FOR X=O TO 39 O=PEEK(X+A) IF 0>127 THEN 0=0-128: R$=CHR$(18):O$=CHR$(146) P=0-((0<32 OR D>95)*64)-((0>63 ANO 0<96)*32) P$=P$+R$+CHR$(P)+O$ R$="":O$="" NEXT X PRINT#4. This can be achieved quite easily with the use of several of the kernal routines. = 65469 = 65466 = 65472 = 65481 = 65490 . 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 1**************** 1* PRINTER DEMO * 1**************** 1 ORG $COOO LDA JSR LDA TAX LDY JSR JSR LDX JSR 160 170 OP 180 190 200 210 220 230 240 TAB 250 270 280 290 300 310 SETNAM SETLFS OPEN CHKOUT CHROUT start address #0 SETNAM 0 = no {ilename LFn=4 #4 Device No. BYT 32.82.77. then get next character JSR CLALL All done so dose all channels Back to BASIC RTS BYT 65.X Get character {rom table JSR CHROUT Output to printer INX Increment counter Last item in table? CPX #34 BNE OP No.The MPSB01 Printer 415 return which causes the printer buffer to be emptied .82.ensuring that all the data is printed.70. 68.71. = 4 No Secondary Add #255 SETLFS Set up Logical File Open{ile OPEN LFn =4 #4 CHKOUT Open channel tor output LDX #0 Initialise counter LDA TAB.72.

189.Part 2 416 320 CLALL = 65511 The program will output the data in the table to the printer . To change the start address you must change the value ofS in line 10. The program could be easily modified to dump the contents of any area of memory to the printer by increasing the size ofthe loop labelled OP.69. 1 10 20 30 40 50 20000 20010 20020 20030 20040 REM LOADER FOR PRINTER M/C 5=49152 FOR Z=5 TO 5+71 READ D:POKE Z. 255 DATA The following is a BASIC program to load the machine code.13 .32.38.32 DATA The data in the table could contain control characters to change the output from the printer.79. 34 DATA 208.The Commodore 64 Omnibus . the message «PRINTED FROM MACHINE CODE PRO GRAM'.201.73. DATA 79. 78. The code is relocatable can be placed anywhere in memory. NEXT Z END DATA 170.




APPENDIX 2 BASIC COMMANDS ABS(N) Returns the absolute value of a number (removing the minus sign). Chapter8 CHR$(N) Converts ASCII codes to characters in string form. Returns the value TRUE if both operands are true (1). Chapter9 ASC (C$) Function. Chapter7 . or of the first character of astring. Can also operate on binary values ofnumbers. See Chapter 8 AND Logical operator. Gives the angle in radians whose arctangent is N. A = BANDC AisTRUE if Band C are both TRUE. Chapter7 ATN(N) Function. Returns the ASCII code of a character.

arrays. Chapter8 definable . Chapter 15 CONT Restarts program after a break. etc) Chapter 15 CLR Clears variables. Chapter6 DEFFNA(N) Defines a user function. Any output normally printed on the screen will be directed to the device specified. and makes the memory available to BASIC pro grams. Chapter5 COS(N) Gives eosine of angle. printer. Chapter8 DATA Marks a list of string or numeric data written into a program. to a peripheral device (disk. Only possible if no alterations have been made to the program. whieh must be given in radians. from memory. Chapter 16 CMD(N) Transfers ou tpu t to the specified file number. N. in the same format. etc. The items must be separated by eommas.BASIC Commands 421 CLOSE(N) Closes a channel.

The variable may . Assigns key value to variable. Chapter8 FOR Begins loop. Chapter8 FNA (N) Calls function defined by DEFFN.M) Dimensions arrays. Acts as natural antilog function. in which case variable is increased by 1. Chapter4 END Ends program. For example: FOR N = A TO B STEP C All lines as far as NEXT command are repea ted wi th value of N increased each time from A to B in steps of C. Arrays of one dimension with up to 10 elements may be used withoutDIM. Pro gram may be restarted using CONT. STEP may be omi tted. Chapter 10 GETN Used for single character input. Chapter5 FRE (0) Returns the amount of memory at present unused by BASIC. Chapter5 EXP (N) Function returning exponential of N (e N ).422 The Commodore 64 Omnibus DIM A(L.

Data is in the form of strings u p to 80 characters in length. Similar to GET. returning to instruction after GOSUB when RETURN is encountered. Chapter5 IF (condition) THEN (action) If the condi tion is true the action after THEN is carried out.N Prompts the operator for an input and assigns it to a variable. Chapter5 GET#(N) Reads a single character from the specified file or device. in which case any key may be pressed. otherwise the program continues at the next line. Chapter5 GOTO Program branches to the specified line. f. The variable may be a number or string: the input data must correspond. Chapter4 INPUT#(N) Retrieves data from the specified file number. . Chapter 15 GOSUB Pro gram branches to a subroutine at the specified which number keys only may be pressed. or a number variable. Chapter 5 and Chapter 9 INPUTN INPUT «<data".BASIC Commands 423 be astring variable. above.

(. LIST Lists the specified lines of the program on to the screen.D. 75} returns 3. Chapter8 LEFT$(C$. Secondary address A specifies start address of program.A Reads prog--ram file A$ from device number. Chapter7 LEN(C$) Gives the number of characters in the string. the tape unit). For example: INT( 3. Chapter 15 .N) Returns the first N characters of the string. Chapter7 LET Optional. D (ir unspecified. Chapter 15 INT(N) Returns integer component of real number. May be used when assigning values to variables: LET P = 5 and P = 5 have the same effect. Chapter4 LOADA$.). default= 1.424 The Commodore 64 Omnibus delimited by CHR$(13) .) or (:). (.

FOR. Returns value TRUE if either or both operands are true. Reverses truth of expression (e. The variable need not be specified. If N is larger than number of items in list no branch occurs. Can also be applied to binary values ofnumbers.N) Returns N characters of string beginning at the Xth character.BASIC Commands 425 LOG(N) Returns the base 10 logarithm of a number. Thus: .X. Chapter5 NOT Logical operator. Chapter4 NEXTN Marks end of loop begun by . Chapter5 OR Logical operator. Chapter7 NEW Clears a program and i ts variables from memory. Chapter5 ONNGOTO Program branches to Nth destination in list. NOT TRUE returns FALSE). Chapter9 ONNGOSUB Program branches to Nth subroutine in list. Chapter8 MID$ (C$.g. If N larger than number of items in list no branch occurs.

Chapter 15 POKE LOC. numbers or characters on the screen. Chapter4 PRINT Puts data. Chapter9 PEEK(LOC) Gives the contents ofmemory location LOC.N Puts value of N into memory location LOC. The number in brackets has no significance. Chapter6 .426 The Commodore 64 Omnibus A = B OR C A is true if B or C is true. Chapter 15 POS (0) Gives the present horizontal posi tion of the cursor on the display. May be wri tten as (1'. Can also act on binary values ofnumbers.255. Chapter3 PRINT#N Writes data to the specified file. Chapter 15 READ Copies items from DATA statements into variables. N must have value 0 .

otherwise execution begins at the lowest numbered line.N) Returns the N righ tmost characters of string C$.BASIC Commands 427 REM Allows remarks to be inserted in pro grams as an aid to clarity. Remarks are i_gnored when program is run. All variables are cleared. Chapter 8 RUN Begins execution of BASIC pro gram. A li ne number may be given. Program returns to the instruction after the GOSUB instruction which called the subroutine. Chapter6 RETURN Marks end of subroutine. reseeds random number generator. Chapter 7 RND(N) If N > 0. Chapter 5 RIGHT$ (C$. If N < 0. returns random number. Chapter4 . Chapter4 RESTORE Returns READ pointer to first DATA item.

zero or negative. 0 or -1 according to whether number is positive. N must be 0-255. Chapter8 STATUS Returns status of the last Input / Output operation. Pro gram may be restarted using CONT. Device number D specifies tape(1) or disk(8). Returns the sine of a number in radi ans.428 The Commodore 64 Omnibus SAVEA$. Chapter4 STR$ (N) Converts numbers to strings of numeric characters. with the name A$. Chapter15 SGN(N) Returns 1. A message 'BREAK IN xxx' is printed.. Chapter4 SQR(N) Returns the square root of the argument.A Stores the program currently in memory onto tape or disk.D. Chapter8 SPC (N) Prints N spaces on the screen. Chapter8 STOP Stops execution of program. Abbreviated to ST. Chapter8 SIN Function. Chapter7 .

Chapter5 TO See FOR. Chapter8 THEN See IF. Chapter5 USR(N) Calls machine code routine at address previously specified. Chapter 16. Chapter 16 . Returns the time since power up or reset in Hours. which must be in radi ans. Chapter5 TIME Abbreviated to TI. 18 TAB(N) ~oves the cursor N places from the left edge of the screen in a PRINTstatement. Chapter5 TIME$ Abbreviated to TI$. Returns the contents of the floating point accumulator after subroutine isrun.BASIC Commands 429 SYS(N) Calls a machine code subroutine at the specified address. The value in brackets is placed in the floating point accumulator. Minutes and Seconds. Reads the system clock. Chapter4 TAN(N) Gives the tangent of an angle.

Chapter 16 . Chapter7 VERIFY Compares a specified pro gram fi le wi th the program currently in me~ory to check for correct savlng.430 The Commodore 64 Omnibus VAL (C$) Converts string of number characters to number.Y Program pauses until the con ten ts of a memory location change in a specified way.X. Chapter 15 W AlT LOC.

APPENDIX 3 BASIC TOKENS & ABBREVIATIONS COMMAND ABS AND ASC ATN CHR$ CLOSE CLR CMD CONT COS DATA DEF DIM END EXP FN FOR FRE GET GET# GOSUB GOTO IF ABBREVIATION DEC TOKEN aB aN aS aT eH clO cL cM cO dA dE dl eN eX fO fR gE gaS gO HEX TOKEN 182 175 198 193 199 160 156 157 154 190 131 150 134 128 189 165 129 184 161 B6 AF C6 C1 C7 AO 9C 9D 9A BE 83 96 86 80 BD A5 81 B8 A1 141 137 139 8D 89 8B .

432 The Commodore 64 Omnibus INPUT INPUT# INT LEFT$ LEN LET LIST LOAD LOG MID$ NEW NEXT NOT ON OPEN OR PEEK POKE POS PRINT PRINT# READ REM RESTORE RETURN RIGHT$ RND RUN SAVE SGN SIN iN leF IE 11 10 ml nE nO oP pE pO ? pR rE reS reT rl rN rU sA sG si 133 132 181 200 195 136 155 147 188 202 162 130 168 145 159 176 194 151 185 153 152 135 143 140 142 201 187 138 148 180 191 85 84 B5 C8 C3 88 9B 93 BC CA A2 82 A8 91 9F BO C1 97 B9 99 98 87 8F 8C 8E C9 BB 8A 94 B4 BF .

433 BASIC Tokens & Abbreviations SPC SQR STATUS STEP STOP STR$ SYS TAB TAN THEN TIME TIME$ TO USR VAL VERIFY WAIT + * / = NOTE: sP sQ ST stE sT stR sY tA tH TI TI$ uS vA vE wA 166 186 A6 BA 169 144 196 158 163 192 167 A9 90 C4 9E A3 CO A7 164 183 197 149 146 170 171 172 173 178 A4 B7 C5 95 92 AA AB AC AD B2 --.indicates either no abbreviation or a non-tokenised keyword .


. For example. or a number it cannot handle.APPENDIX 5 BASIC ERROR MESSAGES If the CBM 64 encounters a command which it is unable to execute. the program will stop. and XXX X is the pro gram line at which the error has occurred. as are the values assigned to all variables at the time ofthe error. The program is retained in the computer. and a message of the form ***** ERROR IN XXXX will be displayed. an error message will be displayed. and the possible reasons for them: BADDATA The data received from a file is not of the type expected. where ***** represents the type of error. In immediate mode. the error message takes the form *****ERROR The following descriptions explain the error messages. If the error occurred while running a program. the file contains string data but the program is trying to input numeric data.

using the command CO NT. BREAK Displayed when pro gram is halted with the RUN/STOP key. DIVISION BY ZERO It is impossible to divide by zero. for example: Z(9. if the pro gram has been edited in any way. and an attempt has been made to access files on that device. 9 .•• when Z is a two-dimensional array. 9 ) = A . EXTRAIGNORED An attempt has been made to enter too many items in response to an INPUT statement.. or the wrong n umber of dimensions has been used. The extra data is not considered. CAN'T CONTINUE You may not continue the RUNning of a program. .436 The Commodore 64 Omnibus BAD SUBSCRIPT An array element outside the dimensions of that array has been accessed. DEVICE NOT PRESENT Displayed when the specified device is not connected to the computer.

BASIC Error Messages 437 FILE NOT FOUND With tape systems. . this means that an end of file marker has been encountered. FORMULATOOCOMPLEX Aseries of string handling functions are too complex to be carried out in one step. They must be split into smaller steps. ILLEGAL DIRECT The following BASIC commands may not be used in Immediate mode: DEFFN GET GET# INPUT INPUT # ILLEGAL QUANTITY A parameter passed to a mathematical or string function was outside the allowed range for that parameter. In the case of disk units the file does not exist on this disko FILE NOT OPEN A file which has not previously been OPENed has been specified in a file handling command .

but there is either no DATA.438 The Commodore 64 Omnibus LOAD The computer has been unable to LOAD the program from tape and has aborted the attempt... or all the DAT A has previously been read. OUT OF MEMORY Either the program is too large. OUTOFDATA This error occurs when a READ command is executed. too many GOSUBs. NEXT loops have been incorrect1y nested. NOT INPUT FILE An attempt has been made to read data from a file which has previously been specified as a write only file. NOT OUTPUT FILE An attempt has been made to write data to a file which has previously been specified as a read only file.. or you have allocated too much space for arrays with the DIM command. or you have used too many variables. . The pro gram either tried to read too much data. or there was insufficient data in the DAT Astatement. too many FOR . NEXTWITHOUTFOR The variable in a NEXT statement has no corresponding FO R statement or FO R •. NEXT loops.

If an underflow occurs. the result is given as zero. REDIM'D ARRA Y After an array was DIMensioned.and i ts length has exceeded 255 characters. REDO FROM START Astring function has been entered when the program was executing an INPUT statement. The message will be repeated until a number is entered.70141 * E38. was larger than 1. or a direct1y entered .made up from several smaller strings joined together . RETURN WITHOUT GOSUB An attempt has been made to execute aRETURN statement which was not preceded by a GOSUB statement. number. and no error message is displayed. a statement DIMensioning the same array was encountered. SYNTAX This can be caused by : Use of a non-existent (or mispelled) BASIC command Missing brackets Incorrect punctuation Missing parameters Illegal characters .BASIC Error Messages 439 OVERFLOW The result of a calculation. STRING TOO LONG Astring has been concatenated .

. or vice-versa. A numeric argument was passed to a function requiring astring argument.The Commodore 64 Omnibus 440 TYPE MISMATCH An attempt has been made to assign a numeric value to astring variable. UNDEF'D STATEMENT The pro gram attempted to GOTO. For example: PR INT ASe ( A) instead of PRINT Ase ( "A" ) or A=Z$ A$ = 2 instead of A=Z instead of A$ = " 2 " UNDEF'D FUNCTION An attempt to reference an undefined user defined function has been made. THEN or RUN anon-existentstatement. VERIFY The program on tape is not the same as the program currently in memory. or vice-versa . GOSUB.

APPENDIX 6 DOS ERROR MESSAGES 20 READERROR The DOS has been unable to read a block of data either an illegal track and sector have been requested or the disk has been corrupted or has been protected against copying. . 24 READ ERROR The DOS has decoded the data incorrectly possibly owing to poor electrical connections within the drive or between the drive and the illegal track and sector have been specified. 21 READERROR The sync byte of the requested track cannot be read . or the disk drive unit requires servicing to align the head. the disk isn't inserted in the drive correct1y.either an unformatted disk or one formatted under another DOS is present. 22 READERROR An incorrect1y wri tten block has been encoun tered . 23 READERROR A checksum error has occured .one or more of the bytes in a block has been read incorrect1Y' causing the checksum to fail.

caused by bad disk format or hardware failure. 26 WRITE PROTECT ON The DOS has detected the presence of a wri te protect tab over the wri te protect notch. 29 DISK ID l\'IISl\'IATCH The DOS has detected a non initialised disko 30 SYNTAXERROR The command sent to DOS via Channel 15 illegal. 27 READ ERROR A checksum error in the header for a data block has been detected and the block has not been transferred to DOS memory .possibly due to poor earthing connections. IS .442 The Commodore 64 Omnibus 25 WRITE ERROR The data block written to disk has been checked against that in DOS memory and been found to be incorrectly written. 28 WRITE ERROR A time-out error has occurred as the DOS tried to locate the sync byte for a data block . 31 SYNTAXERROR The command sent to DOS is invalid.

DOS Error Messages 443 32 SYNTAXERROR The command se nt to DOS contains more than 58 characters. 52 FILE TOO LARG E The file pointer has been positioned to a point where a disk overflow will occur if data is written. 33 SYNTAXERROR The file name in a command is invalid. . 50 RECORD NOT PRESENT The file pointer has been positioned at a point after the last record of a relative file on the disko This doesn't constitute an error if data is to be written (Le. Remember that the carriage return terminator counts as one character. 51 OVERFLOW IN RECORD An attempt has been made to write too much data to arecord in a relative file. 34 SYNTAXERROR Either no file name was sent or the syntax of the command was incorrect causing the DOS to misinterpret the command. if a new record is being created). 39 SYNTAXERROR An unrecognisable command has been sent to DOS.

66ILLEGALTRACKANDSECTOR An attempt has been made to access an illegal track and sector . 62 FILE NOT FOUND An attempt has been made to access a non-existent file. 64 FILE TYPE MISMATCH The file type in a DOS command differs from the type given in the directory for that file. .444 The Commodore 64 Omnibus 60 WRITE FILE 0 PEN An attempt has been made to open a file for reading be fore it has been closed after a write operation. 63 FILE EXISTS An attempt has been made to save a file under a name which is already in the directory. 61 FILE NOT OPEN An attempt has been made to access a file that has not been opened. The parameters returned with this message define the track and sector n umbers of the next free higher numbered block. 65 NO BLOCK An attempt has been made to allocate a block which is unavailable according to the BAM.

72 DISKFULL Either no blocks are available or the maximum of 144 directory entries has been reached. .possibly caused by overwriting the BAM. 70 NO CHANNEL The requested channel is not available. or all channels are in use. 71 DIRECTORYERROR A discrepancy exists between the BAM count and the directory . Re-initialise the disk to force DOS to recreate the BAM. 73 DOS MISMATCH An attempt has been made to write to a disk formatted under a non-compatible DOS.DOS Error Messages 445 67 ILLEGAL SYSTEM TRACK OR SECTOR An attempt has been made to access an illegal· system track or sector. 74 DRIVE NOT READY No disk is present in the drive.

The first declared variables are the first in the table and are found more quickly. and you may find it useful to keep a 'slow'. 1 Remove all unnecessary spaces. but easy-to-follow version ofyour program should you wish to amend it at a later date. 5 Use the zero elements of arrays when possible. A small speed increase will result. 6 Assign often . this is usually at the expense of clarity. Unfortunately.APPENDIX 7 SPEEDING UP PROGRAMS There are several things you can do to increase the running speed of your BASIC pro grams. This is especially important in FO R . 2 Always use variables instead of constants.used variables early on in the program. . REMs and indentation from the program. The 64 stores all variables in a table.. NEXT loops.. 3 Use as many statements per line (separated by':') as possible. 4 Re-use the same variables whenever possible. The CBM 64 can handle variables much more rapidly than numbers. because BASIC will not have to skip over redundant spaces to find executable commands.

to allow you to regain control üfthe computer! 10 Programs involving large amounts of calculation but not requiring the screen display may be speeded up by turning off the screen. with a li ne such as: 100 POKE 53265.Speeding Up Programs 447 7 Put all subroutines near the start of the program.PEEK(56334) OR 1 Remember to include an enable statement before the pro gram ends. and subroutines having low line numbers will be found and executed more quickly than those at the end of the program.PEEK(1) AND 251 and enabled each time you want to use INPUT or GET by 200 POKE 1. NEXTloops. The computer searches through the whole program für a subroutine each time a GOSUB command is executed..PEEK(53265)AND 239 The screen can be turned back on to display the resul ts of the calcula tions wi th a statement: 200 POKE 53265.PEEK(1) OR 4:POKE 56334..PEEK(53265) OR 16 . 8 Omit the variable after NEXT in FOR . 9 In pro grams where the keyboard is not often used. the routines which scan the keyboard can be disabled within a program with a line: 100 POKE 56334.PEEK(56334) AND 254:POKE 1.


G -------------------------E _________________________ c F D _________________________ A B _________________________ F G D E _________________________ B C A -------------------------EGC F -------------------------A DB F G The lengths of notes are indicated by the note shape: ASemibreve aMinim a Crotchet aQuaver a Semiquaver j ) is twice as long as which is twice as longas which is twice as long as which is twice as long as .APPENDIX 9 MUSICAL NOTATION This appendix will not teach you all about music. Music is written by positioning symbols which represent the length of notes on a framework (called astave) representing the pitch. but it contains the basic infonnation you need to translate sheet music into 64 programs.

Examples are: . ff f Veryloud Loud mf Moderately loud mp Moderately soft p Soft pp Verysoft <:::::::: Getlouder ~ Get softer Speed is indicated by markings which may be above or below the stave.450 The Commodore 64 Omnibus V Tails on notes may go up or down). J_J =J Volume is indicated by markings below the stave. The feathers on quavers and shorter notes may be joined where they appear in groups: A dot after a note means that it is made half as long again as a normal note: J. = J_J The mark is a tie which means the notes are joined together.

All other markings which may appear on sheet music (and there are many ofthem) can be ignored. and not worry too much about what is written on the music. # (sharp) means that the note should be raised by one semitone and b (flat) means that the note is lowered one semitone. . Pictures at an Exhibition Here is the beginning of Pictures at an Exhibition. one of the examples used in Chapter 7. Two other markings which may appear next to notes are # and b. The best thing to do is to adjust your program until the speed sounds right. there are many other Italian words and phrases which may be used. The notes 'p ~ j Jj - tJ rIcJ rrrj J I I - I shown in this music correspond to the notes represented by the first two items of every group of six in the DATA statements in the program.Musical Notation Presto Allegro Allegro moderato Moderato Andante Largo 451 which me ans Fast Quite fast Moderately fast Medium pace Slow Veryslow U nfortunately.

.452 The Commodore 64 Omnibus Note the <flat' symbols (b) on the lines of the stave corresponding to the notes Band E. These mean that all B's and E's throughout the music are sharpened.

A collection of 1024 of these bytes is called a KILOBYTE.they use a numbering system known as Binary Notation. Computers use the binary system because they are able to recognise and differentiate between only two states . We are more used to a system called Decimal Notation. In the computer memory. or k for short. or BIT. We have described a byte as a collection of eight bits. and computers store data in the form of groups of eight ofthese bits. one memory location is able to store one Byte of data (eight bits). is 48 * 1024 * 8 bits). in which quantities can be represented by combinations of up to ten symbols (the numbers 0 to 9). like this: 11111111 . Binary notation is a means of representing quantities with groups of ls and Os.APPENDIX 10 NUMBERING SYSTEMS Computers store and operate upon numbers in a different way from humans .ON and OFF. known as BYTES. A single 1 or 0 is called a BInary digiT. These two states can conveniently be represented by 1 (ON) and 0 (OFF). for example. We can get an idea of the data storage capacity of a computer from the number ofk ofmemory it has (48k.

we can see why this number represents 255: 1 *128 1 * 64 1 * 32 1 * 16 1 * 8 1 * 4 1 * 2 1 * 1 + 255 You'll notice that 255 is the biggest number we can represent with an 8-bit binary number. Binary notation uses this same fpl ace value' principle. each digit is worth 10 times the one to its right. which represents 255 in decimal notation.Numbering Systems 454 This is an 8-bit binary number. H T U 255 means: 2*100 + 5*10 + 5*1 In other words. we must first examine the decimal number and see wh at it means. Hence this . 12864 32 16 8 1 1 1 1 1 4 2 1 111 By adding up. except each bit in a binary number is worth double that to its right. We can assign values to the eight bits in the same way as the fhundreds. To see how this is so. tens and units' assigned to the digits of a decimal number.

As a further example. To find its binary representation. and the remainder becomes a bit in the binary number. This principle also applies to binary numbers. To perform the sum: 105 + --. Let's perform the same calculation with the binary forms of105 and 19: .li 124 we add up the digits in each column to form that digi t of the answer . An example will make this clear. we continuously divide by two. let's take the decimal number 170. 170/2 85/2 42/2 21/2 10/2 5/2 2/2 1/2 = = = = = = = = 85 42 21 10 5 2 1 0 remainder 0 1 0 1 0 1 0 1 giving us the binary number 10101010 (reading upwards) ADDITION OF BINARYNUMBERS Binary numbers can be added together in the same way as decimal numbers. we generate a carry into the next column. If the resul t of this addition is greater than 9.The Commodore 64 Omnibus 455 is the largest number we can store in a single memory location.

then add it to the other number. 50 in binary is: Change Is to Os: Adding 1 gives Its two's complement 00110010 11001101 11001110 Now add this to the binary for 100: . we form the two's complement of the number to be subtracted. To subtract two numbers in binary. which uses one bit of the binary number (the most significant bit. by changing all the Os to Is and all the Is to Os. first we find the two's complement of 50. To perform the sum in binary. As an example we'll subtract 50 from 100 : 100 50 01100100 00110010 50 00110010 (the answer we want). since it can only tell the difference between on and off.456 Numbering Systems 01101001 00010011 01111100 + In the case of binary addition we generate a carry when adding 1 to 1 (in columns 1 and 2 in our example). often labelled bit 7) as a sign bit. then adding 1. NEGATIVE BINARY NUMBERS You might have wondered how the computer can recognise negative numbers. This is achieved by a method known as 'two's complement' notation.

because it is so convenient. Y ou will frequently encounter references to hex. and one way in which binary numbers can be made more digestible is by representing them in hexadecimal notation. N otice that a carry was generated. using the symbols 0 to 9 and A to F as follows DECIMAL 0 1.... A consequence ofusing bit 7 as a sign bit is that the range of numbers we can represent with an 8-bit number is restricted to -128to +127 HEXADECIMAL Manipulating numbers in binary is a lot easier for a computer than it is for a human. usually as memory addresses. or hex. . F 10 11 Thus FF (hex) represents 255 (decimal) and 11111111(binary).The Commodore 64 Omnibus 1 457 01100100 11001110 00110010 The result is binary 50 . 9 10 11 ••• 15 16 17 HEX 0 1 ••• 9 AB. Hex is a system of counting in base 16. (Which ofthese is easiest to recognise ? 1111111111111111 or 65535 or #FFFF). . indicating that the answer is positive.the method worked.

CHRIN $FFCF 65487 Gets a character from a previously opened input channel into the accumulator.APPENDIX 11 KERNAL ROUTINES ACPTR $FFA5 65445 Inputs a byte from the serial bus into the accumulator. If no channel is opened. the keyboard is assumed to be the input device. Before use caU TALK and TKSA. CIOUT $FFA8 65488 Sends the character in the accumulator to aserial bus device. CHROUT $FFD2 65490 Sends the character in the accumulator to a previously opened channel. CHKOUT $FFC9 65481 Selects a previously opened logical file to be an output channel. CHKIN $FFC6 65478 Selects a previously opened logical file to be an inputchannel. Channel must have been opened by OPEN and CHKOUT routines. The LISTEN and SECOND routines .

lOBASE $FFF3 65523 Loads the address of the start of memory mapped input/output into the X (low byte) and Y (high byte) registers. . CLALL $FFE7 65511 Closes all open files and resets all 1/0 chaneis. CLRCHN $FFCC 65484 Resets all input/output channels.Kernal Routines 459 must have been called to prepare the device for the data. CINT $FF81 65409 Initialises VIC-ll chip and screen editor at the start of a program. GETIN $FFEA 65508 Either loads one character from the keyboard buffer into the accumulator (accumulator contains o if buffer is empty). or gets a character from a serial device. called by CLALL. CLOSE $FFC3 65475 Closes the logical file whose number is held in the accumulator. IOINIT $FF84 65412 Initialises all input/output devices and routines.



The Commodore 64 Omnibus



Commands the serial bus device specified by
number in the accumulator to listen (be ready to
accept data).




Loads data from a device into memory. If
acumulator=O then memory is overwritten by new
data; a 1 specifies a verify operation, the result of
which is returned in ST. SETLFS and SETNAM
routines must be used before this routine.




If carry bit is set, returns address of lowest byte of
RAM in X and Y registers. If carry bit is cleared
before calling, the contents of X and Y specify
lowest RAM address.




If carry bit is set, returns address of the highest
byte of RAM in X and Y. If carry bit is cleared
before calling, pointer to highest byte ofRAM is set
to contents ofX and Y registers.




Opens the logical file set up by SETLFS and
SETN AM rou tines.




If carry flag is set when called, PLOT loads current
cursor position into X and Y registers. If carry flag
is cleared before calling, cursor posi tion is specified
by contents ofX and Y registers.

Kernal Routines





Performs RAM test, sets top and bottom of memory
pointers, sets up cassette buffer and initialises




Reads the high, middle and low bytes of the system
clock into accumulator, X and Y registers
respecti vely.




Returns system status word in the accumulator.




Restores default values of all system vectors.




Saves the contents ofmemory to a device which has
previously been setup by SETLFS and SETNAM
routines. When called the accumulator must
contain an offset to a two byte pointer (stored in
page zero) to the start ofmemory to be saved. The X
and Y registers con tain the address of the last byte
to be saved.




Scans keyboard for key presses. ASCII value of a
key is stored in keyboard buffer.




Returns number of screen columns and rows in X
and Y registers.



The Commodore 64 Omnibus



Sets secondary address for an input/output device
in a LISTEN operation.




Sets up a logical file, whose number is in the
accumulator, device number is in the X register
and command is in the Y register.




Controls the output of error and control messages.
IfBit 7 ofthe accumulator is set, an error message
will be output; ifBit 6 is set a control message will
be output.




Sets up a file name whose length is in the
Accumulator. The X and Y registers must contain
the start address of the file name in low-high byte




Sets jiffy clock to the time specified In the
accumulator, X and Y registers.




Sets timeout flag when an IEEE card is connected.




Tests for STOP key being pressed after calling
UDTIM routine. If STOP key was pressed the zero
flag will be set.

Kernal Routines





Commands the serial device whose number is inthe accumulator to talk.




Sends a secondary address to aserial device after
the TALK routine.




Updates the system clock when interrupt routines
have been modified.




Commands all serial devices to stop receiving data.




Commands all serial devices to stop sending data.




If carry bit is set when this routine is called, the
current contents of the system vector jump
addresses are stored in a table whose start address
is defined by the X and Y registers. If carry is
cleared before calling, the contents of the table
pointed to by the X and Y registers are transferred
to the system vectors.


Adds the eontents of a memory loeation, or a
number, to the aeeumulator, including the earry
bit. Deposits the result in the aeeumulator.

Performs the logieal AND operation between the
aeeumulator and data. Deposits the result in the

Shifts the eontents of the aeeumulator or memory
left by one position. Bit 7 moves into the earry flag
and Bit 0 is set to zero.

If the earry flag is clear program branches to
current address plus a signed displacement ( + 127
to -128).

If the earry flag is set program branehes to current
address plus a signed displaeement ( + 127 to -128).
If the zero flag is set program branehes to eurren t
address plus a signed displaeement ( + 127 to -128).

The 6510 Instruction Set


Performs the logical AND operation between the·
accumulator and memory. If the comparison
succeeds the zero flag is set and Bits 6 and 7 of the
memory location are copied into the V and N flags.

If the N flag is set (the result of the last operation
was negative) the program branches to the current
address plus a signed displacement ( + 127 to -128).

If the zero flag is clear the pro gram branches to
current address plus a signed displacement (+ 127
to -128).

If the N flag is clear the pro gram branches to

current address plus a signed displacement ( + 127
to -128).

Saves the program counter and status register on
the stack and copies the contents of $FFFE and
$FFFF into PCLow and PCHigh.

If the overflow flag is clear the pro gram branches to
current address plus a signed displacement ( + 127
to -128).


The Commodore 64 Omnibus

If the overflow flag is set the program branches to
current address plus a signed displacement ( + 127
to -128).

Clears the carry flag.

Clears the decimal flag.

Clears the interrupt mask to enable interrupts.

Clears the overflow flag.

Compares the accumulator eontents with memory.
Sets the Z flag if they are equal or clears it if not.
The C flag is set if the eon ten ts of the memory
Ioeation are greater than those ofthe aeeumulator.

Compares the X register with memory data.

Compares the Y register with memory data .

Decrements the specified memory Ioeation.

The 6510 Instruction Set


Deerements the X register.

Deerememts the Y register.

Performs the Exclusive OR operation between
memory and the aeeumulator, storing the result in
the aeeumulator.

Inerements the specified memory Ioeation.

Inerements the X register.

Inerements the Y register.

Program exeeution eontinues at the specified
memory Ioeation.

Pro gram exeeution eontinues at the subroutine
eommencing at the sepcified address.
Loads the aeeumulator with data.


The Commodore 64 Omnibus

Loads the X register with data.
Loads the Y register with data.

Shifts the eontents of the aeeumulator or memory
Ioeation right one position. Bit 7 is set to zero and
Bi t 0 transferred to the earry flag.

Performs no operation for two clock cycles.

Performs the Iogical OR operation between the
accumulator and data.

Pushes the eontents of the accumulator on to the

Pushes the processor status register onto the stack.

Pulls the first item of data from the stack and loads
it into the accumulator.

The 6510 Instruction Set


Pulls the first item of data from the stack and loads
it into the processor status register.

Rotates the contents of the specified memory
location one position to the left. The carry flag is
transferred into Bit 0 and Bit 7 is moved into the

Rotates the contents of the specified memory
location one position to the right. The carry flag is
transferred into Bit 7 and Bit 0 is moved into the
Retrieves the status register and program counter
from the stack and returns from an interrupt
Restores and increments the program counter after
a subroutine call and returns from the subroutine.
Subtracts data from the accumulator with a borrow
and stores the result in the accumulator.
Sets the carry flag.

STX Stores the X register eontents at a specified memory Ioeation. SEI Sets the interrupt disable mask.470 The Commodore 64 Omnibus SED Sets decimal mode. TSX Transfers the staek pointer eontents to the X register. STY Stores the Y register eontents at a specified memory Ioeation. TAX Transfers the aeeumulator eontents to the X register. TAY Transfers the aeeumulator eontents to the Y register. . STA Stores the aeeumulator eontents at a specified memory Ioeation.

TYA Transfers the Y register con ten ts to the accumulator.The 6510 Instruction Set 471 TXA Transfers the X register contents to the accumulator. TXS Transfers the X register contents to the stack pointer. .





.....c:............APPENDIX 15 SCREEN MEMORY MAPS . 25 rows 1024 1025 1064 1065 I I I I I I I I I I 40 columns·····················........ ----------------------------- 1062 1063 1102 1103 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I 2144 2145 2184 2185 ----------------------------- I I 2182 2183 2022 2023 The Character Screen Memory Each block represents 1 memory location ----------------------------- 55296 55297 55336 55337 I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I 56216 56217 --------------- 56 54 56255 56256 56257 --------------- 56294 56295 The Colour Memory 55334 55335 55374 55375 .

............. Block Block 0 1 Block Block 40 41 Block Block 920 921 Block Block 960 961 40 columns ............ ~ --------------- Block --------------- Block Block 78 79 --------------- Block Block 958 959 --------------- Block Block 998 999 38 Block 39 25 rows The Bit Mapped Screen Memory Byte 0 Byte 1 Each block corresponds to eight memory locations laid out like this: Byte 2 Byte 3 The address of any byte is: Screen start + 8*Block No + Byte No Byte 4 ByteS Byte 6 Byte 7 .477 The Commodore 64 Omnibus -00(.................

SET2 : + + - - 47 / / [ 48 0 0 E E 49 1 1 29 1 1 50 2 2 i 30 i i 51 3 3 J J 31 ~ ~ 52 4 4 11 K k 32 SPACE SPACE 53 5 5 12 L I 33 ! ! 54 6 6 " 55 7 7 13 M m 34 " 14 N n 3 # # 56 8 8 15 0 0 36 $ $ 57 9 9 16 P P 37 % % 58 17 Q q 38 & & 59 18 R r 39 60 < < 19 S s 40 ( ( 61 = = 20 T t 41 ) ) 62 > > .APPENDIX 16 CHARACTER CODES SCREEN DISPLAY CODES POKE SET 1 SET 2 POKE SET1 SET2 POKE 0 @ @ 21 U u 42 1 A a 22 V v 43 2 B b 23 W w 44 3 C c 24 X x 45 4 D d 25 Y Y 46 5 E e 26 Z z 6 F f 27 [ 7 G 9 28 8 H h 9 I 10 SET 1 ..

65 [i] [J A 87 D W 109 B 88 X 110 [B Ei] 67 El C 89 Y 111 0 0 68 EJ U 0 90 [I] [] [I] [B Ei] Z 112 E 91 ~ ~ D D 0 92 EI3 iJ ~ ~ F EI3 iJ 113 G 93 [JJ 115 H 94 [JJ [jj] 8J D 8J D I 95 ~ ~ ~ 116 117 IJ IJ J 96 SPACE SPACE 118 [] [] K 97 IJ IJ 119 D D 98 66 69 70 71 72 73 74 75 ~ ~ ~ 114 m m 76 0 L ~ ~ 120 U U 77 lSl M 99 D D 121 ~ ~ 78 [2'1 N 100 [Z] 0 0 0 101 D 0 0 79 D 0 122 123 P 102 R R 124 ~ ~ 81 11] Q 103 D D 125 ~ ~ ~ 82 D R 104 ~ ~ 126 83 [!J 5 105 ~ ~ 127 84 D T 106 [] [J 80 ~ ~ ~ ~ ~ The codes from 128 to 255 give the same characters in inverse video.479 The Commodore 64 Omnibus POKE SET 1 SET2 POKE SET 1 SET2 POKE SET 1 SET2 63 ? ? 85 [Lj U 107 CE CE 64 El El 86 ~ V 108 C. C. .

480 Character Codes ASCII AND CHR$ CODES CODE CHARACTER CODE CHARACTER 0 28 RED 56 8 1 29 CRSR RIGHT 57 9 2 30 GREEN 58 3 31 BLUE 59 . 4 32 SPACE 60 < 33 ! 61 = 6 34 " 62 > 7 35 # 63 ? CODE 5 CHARACTER WHITE 8 DisSHIFTC= 36 $ 64 @ 9 En SHIFT C = 37 % 65 A 10 38 & 66 B 11 39 67 ( 12 40 ( 68 D 13 RETURN 41 ) 69 E 14 LOWER (ASE 42 * 70 F 43 + 71 G 72 H 15 16 17 44 (RSR DOWN 45 - 73 I 74 J 18 RVSON 46 19 HOME 47 I 75 K 20 DEL 48 0 76 L 21 49 1 77 M 22 50 2 78 N 23 51 3 79 0 24 52 4 80 P 25 53 5 81 Q 26 54 6 82 R 27 55 7 83 S .

481 The Commodore 64 Omnibus CODE CHARACTER CODE CHARACTER CODE CHARACTER 84 T 113 11 142 UPPER CASE 85 U 114 D 143 86 V 115 [!] 144 BLACK 87 W 116 D 145 CRSR UP 88 X 117 [Li 146 RVS OFF 89 Y 118 ~ 147 CLR 90 Z 119 C 148 INST 91 [ 120 149 92 E 121 93 1 122 [I] [] [l] 94 i 123 EB 152 95 (- 124 ~ 153 96 El 125 154 97 [iJ rn 126 1T 155 98 rn 127 ~ 156 PURPLE 128 157 CRSR LEFT 129 158 YELLOW 130 159 CYAN 131 160 SPACE 132 161 IJ 99 100 101 102 103 El U Ll D 0 150 151 104 0 133 Fl 162 ~ 105 ~ ~ ~ 134 F3 163 D 135 F5 164 136 F7 165 D 0 0 LSl 137 F2 166 R 138 F4 167 D 110 [Zl 139 F6 168 ~ 111 0 140 F8 169 ~ 112 0 141 SHIFT RETURN 170 [] 106 107 108 109 .

.482 Character Codes CODE CHARACTER CODE CHARACTER CODE CHARACTER 171 []3 178 Er3 185 ~ 172 C. Character 255 is the same as 126. Characters 224 to 254 are the same as 160 to 190. 179 ~ 186 0 173 [g 180 D 187 174 @ 181 [] 188 ~ ~ 175 D 182 189 176 [B ~ 183 CI D U 177 184 190 191 ~ ~ ~ Characters 192 to 223 are the same as 96 to 127.

Bit Mapped Screen. etc. User Defined Characters.APPENDIX 17 MEMORYMAP Addresses o 1024 2048 40960 49152 53248 55296 56320 57344 65535 Contents Storage for operating system Standard screen memory Random Access Memory BASIC pr0J. BASIC interpreter in ROM Unused RAM VIC and SID chip registers Screen colour memory Character Definitions in ROM Input/Output chip registers Operating system in ROM .ams and varia les.

APPENDIX 18 GRAPHICS LOADER PROGRAMS This Appendix contains BASIC listings of loader pro grams for all the machine code graphics package pro grams described in Chapters 19 and 20. 2 Save the machine code by following the instructions at the end ofthe BIT-MAP routine. Refer to these chapters for details of how the pro grams are used. SAVE and RUNit. How to U se the Loader Pro grams The machine code has been split into 5 pro grams to make it easier for you to enter it in small stages. . To obtain the machine code for the complete graphics package follow these instructions: 1 Type in the BIT-MAP routine loader. 4 Save the machine code by following the instructions at the end ofthe PLOT routine. 5 Type in the FILL routine loader.which will reduce the chances of error. SAVE and RUN it. 3 Type in the PLOT routine loader. Because the routines are divided you do not have to type them all in at once . SA VE andRUNit.

it just resets the pointers to the BASIC RAM area.1 for a program on disk. 7 Type in the DRAW routine loader. 9 Type in the MIX MODE routine loader. SAVE and RUNit.Graphics Loader Programs 485 6 Save the machine code by following the instructions at the end ofthe FILL routine.l. 8 Save the machine code by following the instructions at the end ofthe DRAW routine. 10 Save the machine code by following the instructions at the end of the MIX MODE routine.l for a program on tape. SA VE and RUNit.this will not delete the machine code.110 . 12 When all five routines have been loaded in this way.8. you can combine them into a single program by loading each one like this: LOAD "PROG".0 POKE 46.192:POKE 43. You must type NEW after loading each program . or: LOAD "PROG". 11 When all five machine code routines have been saved.197iPOKE 45. you can save them as one program like this: POKE 44. DATA 0. 2.133.173 DATA to load from tape. 2.169.1 to load from disk. DATA 192.1 FOR TAPE 13 To load the graphics package subsequently.The Commodore 64 Omnibus 486 SAVE "GRAPHICS MC".17.2. or: LOAD "GRAPHICS MC". 221.2. This will cause the loss of any BASIC program in the 64.177 . so be careful! BIT-MAP ROUTINE 10 20 30 40 50 60 10000 10010 10020 10030 10040 10050 REM BIT MAP LOADER FOR X=49152 TO 49331 READ D:POKE X. DATA and type NEW after loading.10.2. OR .32.221.8. 169. use the command: LOAD "GRAPHICS MC". 251.154. 173.177.D NEXT X PRINT"BIT MAP CODE LOADED" END DATA 169.216. 192. 169.169 DATA

101.22.221. 141.41.239.Graphics Loader Programs 487 10060 DATA 10070 DATA 141. 10080 DATA 223. SAVE "BIT MAP":REM ADD . FOR DISK DRIVE PLOT ROUTINE 10 20 30 40 50 60 11000 REM PLOT LOADER FOR X=49336 TO 49593 READ D:POKE X. 10090 DATA NEXT X PRINT"PLOT CODE LOADED" END DA TA 173.0 POKE 46. 208.2.188 .72.187.9. 202.251.96 Saving the Bit-Map Routine machine code After runnning the loader pro gram type in the following commands to save the machine code: POKE 11010 DATA 74.208. 16. 10100 DATA

133.208 11140 DATA 11060 DATA 133. 252. 167.133 11080 DATA 252.193.10 11130 DATA 202.165. 169.2.0. 173.169 11070 DATA 0.190. 4.208 11030 DATA 254.254 11150 DATA 42. 0.133. 145.251.187 11050 DATA 193.208 11100 DATA 11040 DATA The Commodore 64 Omnibus 11020 DATA 193.96 . 11120 DATA 10.41.173. 11090 DATA 237.190. 5.133.101. 24.252.251 11110 DATA 145.175.169.

173 13030 DATA 171.169.168.Graphics Loader Programs 489 Saving the Plot Routine machine code After runnning the loader pro gram. SAVE "PLOT":REM ADD .141. 141.2.D NEXT X PRINT "FILL CODE LOADED" END DATA 176.35.96 Saving the Fill Routine Machine Code After runnning the loader program. 184.2.173 13020 DATA type in the following commands to save the machine code: POKE POKE 46. 43.105. 173.226 . 56.237.192:POKE 43.2.169 13010 DATA type in the following commands to save the machine code: POKE 44. 24.173.8 FOR DISK DRIVE FILL ROUTINE 10 20 30 40 50 60 13000 REM FILL LOADER FOR X=50402 TO 50466 READ D:POKE X.167.

196. 196. DATA DATA 196.170 DATA NEXT X PRINT"DRAW CODE LOADED" END DATA . DA TA 173.56 DATA FOR DISK DRIVE DRAW ROUTINE 10 20 30 40 50 60 12000 12010 12020 12030 12040 12050 12060 12070 12080 REM DRAW LOADER FOR X=49608 TO 50372 READ D:POKE X. DA TA 196.170. 205. 141.56.24 DATA 173. 173. The Commodore 64 Omnibus POKE SAVE "FILL":REM ADD .196.170. DATA 196.56.2. 45.208.73. 192.167. 173 12180 DATA 12110 DATA 173.208 12150 DATA 196.0 12130 DATA 237.196 12210 DATA 32. 168.196 12120 DATA 240.169.76. 12190 DATA 173. 12160 DATA 228.141. 12170 DATA 12200 DATA 141.209. 2.181.Graphics Loader Programs 491 12090 DATA 169. 196.196. 12140 DATA 237.2.176. 173.10.141. .2.141.141. 12100 DATA 141.169.223. 196.141. 12250 DATA 196. 220.180 12290 DATA 173.196.141. 196.184 12280 DATA 192. 160.173.212. 12320 DATA 12310 DATA 110.141. 12260 DATA 12340 DATA 196. 173. 141.168.173. 105.224.196. 196.212.2. 196.196. 12240 DATA 196.32.196. 173.210. 240.223.109. 141. 196.205.196 12270 DA TA . 12230 DATA 109. 196.196.169 12300 DATA 12330 DATA 144. The Commodore 64 Omnibus 12220 DATA 240.169. 12360 DATA 136.140.14. 96.196. 46. 204. 170. type in the following commands to save the machine code: POKE 44. 12400 DATA 203.141. 168 12440DATA 2.196.2 12430DATA 172.46.Graphics Loader Programs 493 12350 DATA 12390 DATA 196. 196.204.2. . 43.216.207 12420 DATA POKE 172. Saving the DRA W routine machine code After runnning the loader pro gram. 141. 208.215. 207. 12370DATA 12380DATA 12410 DATA 173.237.

18 . 169.8 FOR DISK DRIVE .32 .2 08.2 00 DA TA 141.7 6.1 04 DA TA 170.208 .69. 21.169 .494 The Comm odore 64 Omnib us SAVE "DRAW":REM ADD .14 1.1 7. 169.104 . 197.33. 169.11 0 SAVE "MIX MODE":REM ADD .173 .10 1.1 41.2 08.208 .14 1.234 Savin g the MIXE D MOD E routi ne mach ine code After runnn ing the loade r progr am.20 8 DA TA 41.32 .18 . 18.20 8. 173.14 1.1 . 192.2 08. 169 DATA 0.19 7.19 7:PO KE 43.1 69. 64.2 08.20 8. 141.1 1.3.36 POKE 46.1 41. 104.26 .8 FOR DISK DRIVE MIXE D MOD E LOADER 10 20 30 40 50 60 14000 14010 14020 14030 14040 REM MIX MODE LOADER FOR X=50 468 TO 50541 READ D:POKE X.88 .49 .3 .1 27.1 73. 0. 114. 168.208 .1 41.7 .2 5.19 7:POK E 45. 41.1 92. type in the follow ing comm ands to save the mach ine code: POKE 44.17. 25.D NEXT X PRINT "MIX MODE CODE LOADED" END DATA 120. 18.2 0. 67.

8 DATAMAKER This program will convert the contents of any area ofmemory into aseries ofDATA statements which are appended to the DATAMAKER program. LN . With all the routines in the machine you can save them together as one program by typing: POKE 44.192:POKE 43. To use the program enter the line number at which you want the DATA to start. When the program has finished.I. you can load them all into the 64 using the commands: LOAD"PROG".1 to load from tape.8. You must type NEW after loading each program.197:POKE 45.0 POKE 46.Graphics Loader Programs 495 SAVING THE GRAPHICS PACKAGE After creating the machine code for each of the five routines comprising the graphics package and saving them individually. 5 10 REM DATAMAKER INPUT "FIRST DATA LINE NUMBER". delete lines 5 to 500 and save the DAT A statements for use in your program. or LOAD"PROG". and the start and end address of the area of memory you want to convert into DATA statements.110 SAVE "GRAPHICS MC".1 to load from disk.

2) CK = CK+C PRINT C$i IF I<F THEN PRINT"."i NEXT PRINT S=F IF S<E THEN PRINT"LN="LN+I0": S="S+1":E="E":GOTOI00" IF S=E THEN PRINT"LIST" POKE 198.19 POKE 632.13:POKE 633.3 POKE 631.13 END .496 The Commodore 64 Omnibus 20 INPUT "START ADDRESS OF CODE"iS 30 100 110 120 130 140 150 160 170 200 210 300 310 320 330 340 350 500 INPUT "END ADDRESS OF CODE"iE F=S+16:IF F>E THEN F=E PRINT" {CLS}"LN"DATA" i FOR I=S TO F C = PEEK(I) C$ = MID$(STR$(C).

249 AND 83 174 Animation Arithmetic 11 .in Machine Code 241 27 Arrays Array Element 232 231 Array Header Array Variables 230 Assembler 237 204 Assembly Language 62 ASe ASCII code Attack 95 ATN 75 Auto Loading 362 BAM BASIC BASIC Commands BASIC Storage BEEP routine Binary numbers Bit Bit-Mapped Graphics Block-Allocate 354 1 420 212.230 146.INDEX 1525 Printer 1540 Disk Drive 1541 Disk Drive 16 Sprites 6510 microprocessor 403 400 348 307 235 Abbrevi ati ons 419 74 ABS Absolute machine code Buffer Pointer Byte 398 378 374 375 82 37 245 380 89 Cassette unit Channels Character sets eHR$ CHRGET Routine Clock elOSE elR CLRlHOME key Collision detection eMD Colour Colour memory Comparisons in machine code eONT COpy Copying Tapes COS CTRL key Cursor Cursor keys Cursor Down Mode Cursor Up Mode 4 188 128 62 219 38 188 92 10 167 190 12 120 DATA Decay DEFFN DEL key 248 49 359 402 75 12 8 9 407 407 54 95 79 10 .262 377 Block-Execute Block-Free Block-Read Block-Write Boolean algebra Branching .249 Addressing Accumulator 235 Adding commands 220 Addressing Modes 239.227 221 230 127.

260 8 420 1 60 59 424 215 19 .36 2 Display Memo ry 263.46 4 INT 74 Intege r variables 25 Intege r Variables 226 Interpr eter 211 Interru pts 255.498 The Comm odore 64 Omnib us OlM 29 Directo ry 353.26 5 DOS 349 DOS Suppo rt Program 359 DotAd dress 412 Dot Matrix 403 Double Width Mode 411 DRAW routine 281 Drawin g Lines 280 Editing END Envelope Error messages Error status Executing progra ms EXP 10 48 95 221 361 219 Files Fill Program Filter Floatin g Point Variables Floppy Disks FN FOR Forma tting disks FRE Functions 187 292 103 227 349 79 34 352 91 73 GET GET# GOSUB GOTO Graphics . BASIC Languages LEFT$ LEN LET Link Pointe r LIST 299 37 252 211.301.43 7 Headache progra m Hexadecimal numbe rs Hierarchy of operat ions High levella nguag e Homebase Progra m House keepin g 297 234 12 234 383 357 IEEE Disk Drives 401 IF 43 Immed iate mode 8 Immed iate Addressing 239 Index 497 Index Registers 235 Indexed Addressing 250 Indirec t Addressing 250 Initialis e 358 INPUT 29 INPUT# 188 INST key 10 Instruc tion set 237.Symbols .Bit mappe d Graphics Mode Printin g 52 188 46 37 119 15 146 408 77 Graphics Programs 294.314 Interru pt Enable Reg 303 Interru pt Status Reg 303 JR's hat progra m Jumps .360 Disk Drives 400 Disk Status machin e code Kernal Keyboard Keywords.

14 RETURN 47 Reverse video 15 Reverse Mode Pri nti ng 412 RIGHT$ 60 RND 77 ROM 90 RUN 19 RUN/STOP key 11 Running Machine Code 258 SAVE 185 Saving Programs 185.355.362 Scratch 359 Screen Dump Program 413 .272 PEEK POKE POS PRINT PRINT# Processor status register 499 13.234 MID$ 61 Mixed Mode Display 312 Modulation 109 Monitor 7 MPS801 printer 403 Multicolour Graphics 266 Music 93.234..55 188 Program Counter 236 18 236 Quitting DOS 5.90 57 8.Index LOAD 184 184 355.398 Memory Execute 399 Memory maps 239.427 Numbering systems 230 ON . 158. 332 NMI 21 352 34 255 NOT 84 NEW New disks NEXT Notes 333. GOTO OPEN Operating System OR 49 49 187 204 84 90 Plotting Points 273 Pictures program 340 Pixel 127.. GOSUB ON .420 RESTORE 55 RESTORE key 11.1 363 RAM Random numbers Random Files Raster Register Raster Scan 90 Prog~m 77 373 302 301 READ 53 Real variables 25 Register 91 Relative addressing 251 Relative Files 367 Release 95 REM 32 Rename 359 Renumber Program 217 Reserved words 24. 246 Memory Read 399 Memory use 89. 246 Memory Write 398 Menu 315 Mice 316 Microprocessor 204...214.362 LOG 76 Logical Operations 256 Loops 34 Lowercase 14 Loading programs Loading Programs Machine code 204.

500 The Comm odore 64 Omnib us Screen memo ry 120.25 3 STATUS 190 Status Register 235 STEP 35 STOP 49 Stoppi ng progra ms Storing Machin e Code 259 String Variables 227 String variables 26 STR$ 63 Structu red progra mming 207 Su brouti nes 46 .26 3. 265 Sector 349 Seque ntial Files 364 SGN 75 Shifts 257 SID Chip 331 SID registers machin e code 252 Sustain 95 Syntax errors 221 SYS 204 TAB Tab Print Head TAN Television THEN TIME TIME$ TO Token 57 410 75 4 43 39 39 34 214 Track Tunes 349 331 Upper ca se User User define d functio ns User define d characters User Friend ly USR 14 399 79 129 315 205 VAL 63 Valida te 358 Variables 22 Variab le display prog 228 Variab le dump progra m 230 Variab le Storag e 225 VERIFY 185 VIC-II Chip 130.235 Side Sectors 368 Simple variables 225 SIN 75 Sketchpad Program 317 SPC 56 Sprites 158 SQR 73 Stack 253 Stack Pointe r 237.301 WAIT 206 X registe r 235 Y registe r 235 Zero Page Addressi ng 240 . 263.

Sustain & Release for each voice Sets frequency & waveform for each voice . Decay. providing 36 extra BASIC commands which give you full control over the Graphics.SUPER BASIC SUPER BASIC is an extension to the standard BASIC 2. and add many of the features found in more modern versions of BASIC. SUPER BASIC COMMAND SUMMARY AT AUTO DEEK DEL DOKE HIMEM OLD PACK PAUSE POP RENUM RESET BLOCK CHIRES CMULTI DRAW FRAME HIRES INK PAPER PLOT SETCOL TEXT FILTER GATE MUSIC QUIET SHAPE SOUND Moves cursor for PRINT@ & INPUT@ operations Automatically generates line numbers 16bitPEEK Deletes blocks of program lines 16 bit POKE Sets the limit of memory for BASIC programs Restores accidentally NEWed programs Removes all REMs and surplus spaces Provides a timed delay in jiffies Removes one address from the RETURN stack Renumbers programs including all branches Resets the 64 Fills blocks on hi-res screen with specified colour Clears hi-res screen and sets hi-res mode Clears hi-res screen & sets multicolour mode Draws lines on hi-res screen in both modes Changes frame (border) colour Returns to previously set hi-res mode Changes foreground (ink) colour Changes background (paper) colour Plots or unplots a point on either hi-res display Sets hi-res colours Returns to the text display Sets up the filtering on SID chip Controls gateing of SID voices Plays musical notes from 8 octaves on any voice Inhibits sound output and resets SID Attack. Sprites and Sound capabilities of your 64.0 of the Commodore 64.


ISBN 0 7126 06661 I enclose my cheque/postal order for f __ (cheques should be made payable to Tiptree Book Services Ltd). Tiptree Colchester. : Century Software I I : To: : I :I : MailOrder Dept.VOLUME SPRCOL SPRITE SPRMOV SPROFF SPRSET SPRSIZ Sets volume for SID chip Set up sprite colour registers Enables sprites Positions sprites on screen Disables sprites Defi nes sprites Defi nes sprite si zes Also included in the SUPER BASIC package is a comprehensive booklet describing how the new commands are used and some example programs. I . Tiptree Book Services Ltd. If you would like to order a copy of SUPER BASIC please cut out or copy the form below and send it with your remittance to the address given. Please debit my Access/Barclaycard account (delete as appropriate). .----------------------------------------------. at f9. ~~~b~. IIIIIIIIIIIIIIIII Name Address----___________________________ Signed (Horne address please if paying by credit card) Please allow 28 days for delivery. Essex C05 OSR : Please send me copies of SUPER BASIC by : Peter Lupton anCf'Frazer Robinson. Ctiurch Road..95 each.