with a Special Section on the Timex/Sinclair 2000 THE ESSENTIAL GUIDE TÜ TIMEX/SINCLAIR HOME COMPUTERS ! The Only Book You'll Ever Need to Become an | Expert at the Timex/Sinclair 1000 and 2000 li ЖДД ЕТП : f "d cundo 3H YIVIINIS/KIWIL ñ. E 1 ' Е E МУГ ы ЕК ie L E S M 4 % 5 | а \ ( ' “ [| | li ( ү ж | я , TY 7 ` ` | E 4 є d] j = у | et Ties | А | E ч т, d x I ^ ; s a | - EN А Gs > i E»: "A "v 4 y "4p". THE ESSENTIAL GUIDE TO TIMEX/SINCLAIR HOME COMPUTERS The Only Book You'll Ever Need to Become an Expert at the Timex/Sinclair 1000 and 2000 by PETER MORSE, IAN ADAMSON BEN ANREP and BRIAN HANCOCK A TOUCHSTONE BOOK Published by Simon & Schuster, Inc. NEW YORK We are grateful to Sinclair Research for their cooperation This book was published in England under the title The Century Computer Programming Course Copyright © 1983 by Eosoft All rights reserved including the right of reproduction in whole or in part in any form A Touchstone Book Published by Simon & Schuster, Inc. Simon & Schuster Building Rockefeller Center 1230 Avenue of the Americas New York, New York 10020 Published by arrangement with Century Publishing Company, England TOUCHSTONE and colophon are registered trademarks of Simon & Schuster, Inc. Manufactured in the United States of America 10 98 765 43 2 1 Pbk. Library of Congress Cataloging in Publication Data Main entry under title: The Essential guide to Timex/Sinclair home computers. (A Touchstone book) British ed. published as: The century computer programming course. 1. Timex 1000 (Computer)—Programming. 2. Timex Sinclair 2000 (Computer)—Programming. 3. Basic (Computer program language) I. Morse, Peter (Peter L. R.) II. Title. QA76.8.T48E77 1983 001.64'2 83-9090 ISBN 0-671-47069-8 Pbk. IMPORTANT NOTE FOR ALL READERS This book uses the Sinclair version of single keystroke BASIC as featured on the ZX81 and Spectrum microcomputers. In the States the ZX81 has been marketed as the Timex/Sinclair 1000 and the Spectrum is known as the Timex/Sinclair 2000. American readers should note that throughout the text we refer to these machines by their UK names. There are a few minor differences between the UK version of the ZX81 and the US TS 1000. The first is that the TS 1000 has more ‘on board’ memory (2k) than its UK equivalent. However, this is still insufficient for the scope of this text, and the majority of the programs occurring in the book will require a 16k RAM pack. The second difference is that two keys, which do exactly the same thing, are labelled differently. Thus, NEWLINE and ENTER are equivalent on the ZX81 and the TS 1000, as are RUBOUT and DELETE. On each occasion that these commands occur in the text, readers will find either NEWLINE (ENTER) or RUBOUT (DELETE). For the sake of clarity we have used the ZX81/TS 1000 version of BASIC as the foundation of the book, and have noted those instances where Spectrum (TS 2000) BASIC differs from that used by the ZX81 (TS 1000). Functions and commands exclusive to the Spectrum (TS 2000) BASIC superset are fully explained at the end of the book (Units W2 and W3). In short, the book has been designed to enable its readers to learn how to program using any of the Sinclair machines. Users of the Spectrum should note that all programs are listed in capital letters throughout. To get program results and listings that look identical to those given here the capital letter (CAPS) mode must be used on the Spectrum for all letters input or printed. The first two Units of Part One deal only with the ZX81. The Spectrum user should read instead Unit W1 (page 439) of the Spectrum dedicated Section which forms Part Five of this text. TE РЧ КЛ АЙ oie SOT TOM ГИЛ ГАГИ í; FAD iin “ger former үніне” wh еи фе” ИЯ? = ez deus qo +. теі Craft

eet 7 bonua «canted ‘Hee Kets? volut. йй ay aint arrests ПОЛО grieved bets) tao tari ed gn deabus nord бы? чый oe sura age Tiber: iron «М. заз (eo m £ -GA < ihe и ж ула % «©.» {кулан Ya кзжсжттер bgr там, ъз + Min Pí Г ұлығ | nus зыр“ iai паз 1 D нұйуі, АТИ PART ONE FIRST STEPS Important Note: The first two units of this part are specific to the ZX81. Spectrum users should ignore these pages and directly GOTO the first Spectrum specific section (W1 on page 439) before returning to the main text (Section C on page 19). Зин ERAS LI рч SECTION A: ZX81 MICROCOMPUTER SYSTEM A1: ZX81 Description We assume you have in front of you the components of your ZX81 computer system. It consists of: 1 Тһе ZX81 microcomputer with its touch-sensitive keyboard. 2 The Sinclair 16k RAM pack (Random Access Memory) or a RAM pack of at least 16k produced by one of the other manufacturers for the ZX81. 3 The ZX power supply, with a lead and plug, for connection to the a.c. power supply, and the lead, ending in a jack-plug, to connect the power supply unit to the ZX81. 4 The ZX printer and its connector socket. A domestic UHF ТУ set to be used as a TV monitor. 6 А mono cassette recorder, with power supply lead if not battery powered. The aerial cable which connects the ZX81 to the TV monitor. 8 A pair of cassette recorder leads fitted with 3.5mm jack-plugs оп each end. сл I These components make up a complete system. As far as this text is concerned, the least crucial component is the printer. Without it you can simply ignore the printer-related portions, and will be able to work through the book and learn the BASIC programming techniques just as well. However, it is extremely useful to have a printer both for hard- copy printouts of results, and more importantly for program listings for documentation purposes. There are a large number of ‘add-ons’ and accessories available for the ZX81. None of these are of any interest as far as this book is concerned, and most should be considered only when you have absorbed the text and are going to write programs for specific purposes, which might require the facilities provided by some of these units. A noteworthy exception is a workstation to hold the components of the system securely. There are types available which have on/off switches for the d.c. power supply from the power supply unit, which saves a lot of plug pulling and re-insertion, since pulling the power plug out of the ZX81 is the only way to re-set the computer if it ‘crashes’ (i.e. will not respond to keyboard commands). What ¿s vital is enough memory. RAM memory is measured by kilobytes (‘k’). The basic ZX81 has only 1k of RAM built in (2k on the Timex/Sinclair 1000), and, without an add-on, RAM memory has very little space available for programs. Computers are essentially devices which store and manipulate data, and since programs, data, and the manipulations all take up memory space, an add-on RAM 1 Figure 1 ZX81 SYSTEM DIAGRAM ас. household power supply AERIAL TV MONITOR SOCKET POWER EAR а CASSETTE SUPPLY МІС | RECORDER NOTE: U.S. USERS MAY HAVE ANTENNAE ON/OFF SWITCH FITTED IN AERIAL LEAD, SHOWN AS DOTTED BOX IN DIAGRAM. memory is needed. RAM memory of up to 48k is available for the ZX81, but 16k is more than enough for our purposes. Independently produced RAM packs are usually just as good as those produced by Sinclair. The cassette recorder should be mono, since stereo tape deck recording heads can cause problems, even used on one channel only. The cheaper recorders work somewhat better (due to the less sophisticated audio circuits being better for handling the crude form of the computer’s signals) than more expensive ones, but try to get one with a tape counter, as finding programs without one can be irritatingly time consuming. You should always use the same recorder, as problems can be encountered when playing back tapes recorded on a different machine. Battery-operated recorders actually avoid some potential problems, but must always have good batteries, to keep tape 2 speed constant. The cheapest solution to this in the long term (especially since if you're not sure about the state of the batteries you have to put in new ones) is to buy nickel-cadmium batteries and a charging unit. All recorders have automatic level controls for recording, but some cause problems with their continual variation around the correct level (‘hunting’). Get a model that has been shown to be compatible with the Sinclair computers. Having a TV for exclusive use with your computer system 1s a good idea, to avoid having to unplug and move around elements of your system (it also avoids arguments with non-computing members of the family!). Some problems can interfere with the operation of your computer (leaving to one side things like spilling coffee on it or otherwise abusing it!). The first is overheating. After the computer has been on for some time, it may heat up to such an extent that it ‘whites out’ and wipes out the program you have just finished, except for that last line. This is very irritating, to say the least. Some ZX81s seem to suffer from this more than others. If it is a persistent problem, it can be helped by placing a fairly hefty chunk of metal on top of the case to radiate heat away more effectively. It should be approximately 3 x 2 inches and 0.5 inch deep, have a flat surface to sit on the ZX81 case, and should be placed on the case, above the keyboard, on the left-hand side of the case. lhe corollary to this problem is that you should SAVE a long program being developed or keyed in at intervals, and/or take listings from the printer, to avoid a total loss if you do get a white out. The same problem can also be caused by two other factors, and this procedure will protect against the worst results from these problems as well. The first is that household power supplies are sometimes interrupted, or occasionally have brief large voltage fluctuations. Computers are sensitive to such things, and a crash may be caused. Other than buying a stabiliser which will continue to supply power during such an interruption (of very short duration, but computers work fast!) we cannot protect against a.c. supply fluctuations, but similar results can sometimes be caused by appliances connected to the same local power circuit switching on and off, and this should be investigated if the problem is frequent. The other main source of problems is the connector to the RAM pack and printer via the edge connectors at the back of the ZX81. Movement can be caused in this connector by flexing the system whilst keying in programs. This can be minimised by always pushing the connectors home firmly before switching on, but a better solution is to attach the components to a board, fixing them down to a suitably rigid base with ‘Blu-Tack’ or the double sided adhesive pads that are now available. Fix the printer down as well- the process of tearing off printout can move printer and connector if you are not careful. Note that the method of fixing cannot be permanent, which is why Blu- Tack 3 or a similar plastic fixative is recommended. The edge connectors themselves are gold plated, but they connect to the printed circuit board edges which may become oxidised, causing circuit problems (not necessarily white-outs or crashes — the keyboard may cease to work, or the printer miss lines, for example). Proprietary (non-abrasive) contact cleaners should be used to ensure clean contacts. Other than the problems above, the only maintenance that should be needed is the brushing away of the dust that accumulates in the printer from the burnt-off particles of paper. After removing the paper holder, use a soft small brush (e.g. a small paint brush) to clear away the dust. Pay particular attention to the slot in which the electrode runs, but if, as sometimes happens, the electrode is visible, do not disturb it. (The electrode is a small piece of wire which is normally not visible, but if BREAK has been used it can be left in the middle of the printer slot.) A2: Function of Components This is a programming text, not a manual on computer architecture or computer science. However, we thought it might be useful to provide you with a brief rundown of the functions of each of the components of your microcomputer system. Device Function ZX81 computer board Data processing and control of (inside case) information handling. Input from keyboard or cassette. Output to TV screen and printer. Keyboard Input of information. Programs, data and commands are keyed in. On-line control. TV set Used as V.D.U. (visual display unit) monitor. Provides on-line output of information — visual display of programs, results (data, graphs, pictures) and control commands. Cassette recorder Off-line storage of information. Program data are stored (written) as coded electromagnetic impulses on cassette tapes. They can be played back (loaded) at any time for use again. The computer reads the data from the tape. ZX printer Output device, to provide a permanent printed record of the screen display, program listings or information in the computer memory. Prints on electrosensitive paper. 16k RAM pack Add-on memory enabling large Power Cables programs to be stored and run. K stands for kilobyte. One byte is eight 22/5, which аге the binary digits (0 and 1, represented by on-off switches in the computer) computers work with. A kilobyte is roughly 1000 bytes, hence the name. (It is actually 29, 1024). supply Supplies the d.c. current (9 volts at 1.2 amps) to run the computer, RAM pack and printer, from the household power supply. To interconnect the devices which make up the system. The printer uses the same socket as the memory pack and has an extension socket to allow this. The printed circuit board inside the ZX81 holds and connects the IC (integrated circuit) microchips which provide the computing facilities. These 1 are: Z80A CPU (Central Processing Unit) microprocessor chip which is the heart of the system. It is used in many other microcomputers, and performs the arithmetic manipulations. ROM (Read Only Memory) chip holds the 8k BASIC interpreter which translates BASIC instructions into the machine code instructions that the Z80A operates with. The data in this chip is fixed, hence the name, and also stable — it remains when the power is switched off. 3 RAM (Random Access Memory) chip provides a 1k* memory store. When the memory pack is fitted it blocks off this memory and substitutes its own 16k of memory. This memory is volatile — the data is stored as electrical impulses and is lost When the power is switched off. This memory stores the BASIC programs, the values of variables (including some system variables that the computer uses to organise its own affairs), a memory picture of the ТУ screen display, and the stacks which hold the numbers whilst they are being manipulated. This is covered in more detail in Section U. 4 The Logic chip co-ordinates the operation of the other chips. Also mounted on the board are: the stabiliser for the 5 volt supply the computer takes from the power supply, the TV signal modulator and the sockets for the connecting cables to the ГУ and cassette recorder. *2k on the TS 1006. SECTION B: GETTING TO KNOW THE ZX81 B1: Connecting Up 1 Lay out the ZX81 system devices on your work area as оп page 2. It is far better to have an area where the system can be set up permanently. Failing this, a board can be used to mount the components. Place the a.c. power supply plugs of the power supply, ТУ and tape recorder next to the sockets. A plug board with multiple sockets mounted on it is better than an extension socket fitting. Connect the printer socket into the 23 pin edge connector at the back of the ZX81. Get the slot in the ZX81 board and the block in the printer socket aligned and push in gently but firmly. Connect the 16k RAM pack socket into the extension connector at the back of the printer socket in the same way. This is better done with the ZX81 flat on the table to avoid too much stress on the connectors, which might occur if you are holding up the LAB, With both connectors inserted, push the RAM pack firmly in to ensure the connectors are fully seated home. Connect the power supply cable into the socket marked DC on the left-hand side of the ZX81. Connect one end of the twin jack-plug leads, placing one jack- plug into each of the MIC and EAR sockets on the cassette recorder. Place the other jack-plugs into the ZX81 sockets. It is very useful to have the EAR and MIC sockets marked on the top of the ZX81 case, where the marks can be seen. Use sticky labels of some type to mark which is which, and also the exact centre of the plug socket. This will save much probing of sockets (there are no guides to ensure you get the socket) and peering at the markings on the side of the ZX81, which are scarcely visible when the ZX81 is flat on a surface. The yellow banded plugs should go to both MIC sockets. You can also mark the other jack-plug with E or EAR as a helpful aid. Push the jack-plugs gently in, making sure the tips are in the sockets (which has to be done by feel) until a resistance is felt, then push until they click into place. Waggle them slightly to ensure they are well-seated. Connect the aerial lead into the ТУ aerial socket at the rear of the TV and into the TV socket on the ZX81. A slight twisting motion may be needed if the fit is tight. US Users will find that the TV connects to the antenna lead with standard terminals, and an antenna ON/OFF switch is fitted between the antenna lead and the antenna lead that plugs into the 7 Timex/Sinclair 1000 version of the ZX81. This switch must of course be ON. Straighten the interconnecting cables on your work area at this point. Make sure that the cassette leads are not in contact with any a.c. power leads. SWITCHING ON оомо C 10 11 12 13 Ensure that the TV receiver is off and that no cassette recorder keys are depressed. Plug the power supply, TV, and cassette recorder plugs into the a.c. power supply. Switch on the a.c. power sockets (if they have switches). There are no ON/OFF switches on the ZX81 or on most cassette recorders - they are now powered up. Switch on the TV. Turn the volume control on the ТУ to zero. Turn the brightness control to MAXIMUM. Turn the contrast control to MINIMUM. Tune in the TV. With a rotary tuning control, turn to channel 36. Otherwise select a channel, using the pushbutton or other channel select switch, and tune this channel in. When the ГУ is at the right setting, a small black square with a white K inset appears. This is the K-cursor, and appears on the bottom left- hand side of the screen. U.S. Users should note that the Timex/Sinclair 1000 version of the ZX81 has a channel select switch for Channel 1 or Channel 2 fitted underneath the case. Choose whichever channel is not transmitting in your area, and select this channel on the TV and the computer. Adjust the tuning, brightness and contrast until the cursor is distinct, and the white K clear. Check that the cassette recorder keys function. Insert a blank cassette, and try all the controls. Insert a roll of silver printing paper into the printer and press the button on the right-hand side of the printer to feed some paper through. Check the paper does not rub on either side of the printer as it comes through. Press the key and then the [NEWLINE (ENTER) | key. The printer will start to copy what is on the screen. About 3 inches of paper will be fed through. There will be nothing printed on it as there is nothing on the screen. A message 0/0 will appear at the bottom of the screen. N.B. The bottom two lines of the screen are never printed and are used for keying in program lines and commands. These program lines, when correct, are transferred into an area of 8 memory reserved for the programs by pressing the NEWLINE (ENTER) key. The program lines will then appear on the printer when the COPY command is given. 14 Press characters at random on the keyboard. They will appear at the bottom of the screen. Press and [EDIT | keys together to clear the screen. 15 If the cursor will not appear on the screen switch off the power supply and adjust the 16k RAM pack and printer connections. Switch on the power supply again and retune the TV. N.B. Never adjust or pull out the RAM pack when the power supply is ON, you may damage it. 16 Other components failing to work will probably be caused by plugs not switched on, or fuses blown. Alternatively, it could be that some connections are not being properly made. You should remove and re-insert Jack-plugs and connectors. 17 On leaving your computer: a Leave it connected up b Switch OFF a.c. power supply plugs and TV c Disconnect plugs from sockets. B2: The Keyboard The ZX81 keyboard has 40 touch sensitive keys arranged in 4 rows of 10 keys. At first sight it looks like a typewriter keyboard, but a closer look reveals that some keys have five functions or characters written on them. In fact: Six different characters can be obtained from some keys! The keyboard contains: (1) The digits 0 to 9 (2) The letters of the alphabet printed in upper case (3) The complete BASIC language — instructions — commands — arithmetic, conditional and logical operators — arithmetic functions (4) Grammatical signs and symbols (5) Special control keys (6) Graphics symbols These are all called characters. Notice that words like PRINT, RUN, SLOW, LET, INKEY$ are 9 written on the keys and are printed on the screen when we press that key in the correct mode. The facility of complete words in the BASIC language being printed at the press of a single key is called SINGLE KEYSTROKE BASIC On most other computers you have to key in each letter of, for example, the instruction PRINT. This is inefficient. The ZX81 is very powerful in this respect. The keyboard contains most of the characters in the ZX81 character set and a few special keys. Some 202 different characters are available. Some print on the screen, others are non-printing, e.g. RUBOUT (DELETE). Each of the different types of character 1s described in Section B4. The ZX81 keyboard layout is reproduced in the diagram on the next page. B3: Cursors is] [>] Cursors indicate what operational mode the computer is in and what symbol or name should be typed in next. They appear in inverse video (a white letter in a black square). Keyword mode. ZX81 expects a command a line number or a keyword Keywords are the symbols printed on the keyboard above the keys (see keyboard). SHIFTed keys also function in this mode. Letter mode. Occurs at most other times. ZX81 expectsa letter a number an operator ora special command SHIFTed keys function in this mode. Function mode. Obtained by pressing FUNCTION key (SHIFT, NEWLINE/ENTER). The functions obtainable are printed under each key in white. 10 Figure 2 ZX81 KEYBOARD ГЫ 86791 s e Se a e M CODE PEEK IT ap ж JE es DS Mei ш ч" AG БЕЙ K [ENTER] ARCSIN = Ж: DS COPY CLEAR fis Only one function can be obtained each time FUNCTION is pressed. Graphics mode. Obtained by pressing GRAPHICS key (SHIFT, 9). Mode lasts until the GRAPHICS key is pressed again. In the graphics mode 36 different characters are obtained by pressing the keys with the SHIFT key depressed as well. These are shifted graphics characters. 38 different characters (mainly letters printed in the inverse mode) are obtained by pressing the keys. [s | Syntax error cursor. This cursor appears in a statement line at the bottom of the screen if the computer finds that there is an error in it. It appears when we try to enter an incorrect line of program into memory (i.e. after we press NEWLINE (ENTER) when at the bottom of the screen). The [S | cursor appears next to the last error in the line. (There can be more than one). Editing on the line сап take place immediately. The [5 | cursor disappears when an edit operation is performed. It will re-appear (if necessary) when NEWLINE (ENTER) is pressed again. Current line cursor. When entering statements into the program the last line to be entered is called the current line and is indicated by this symbol placed after the line number. The movement of this cursor up and down the screen, pointing to different lines, is controlled by the { and ^ keys (SHIFT 6 and 7). If EDIT (SHIFT 1) is pressed, the current line is brought down to the bottom of the screen and can be edited. B4: The Different Character Types THE 6 CHARACTER TYPES ON A KEY If we examine a particular key, say [R ] , we can classify the 6 character types, as seen in the diagram below. RUN LETTER <= ec = INVERSE GRAPHICS GRAPHIC INT - KEYWORD On top of the R key is the word RUN. This is a KEYWORD character. All characters printed on the keyboard in this position are KEYWORDS. KEYWORDS will be printed on the screen if the desired key is pressed when the ZX81 is in KEYWORD MODE (1.е. the cursor is on the screen). Exercise If the | К | cursor is at the bottom left-hand side of the screen then enter a keyword. Press the | PRINT | (P) key. Notice that PRINT appears on the screen but the cursor has changed to an cursor and the computer is in the letter mode. This means that it 1s expecting a letter to be keyed in next, e.g. A. If we try to key in another keyword, e.g. , the keyword PLOT does not appear. Instead the letter O is printed. So the rule is: No two keywords may be entered in succession. To clear the screen and return to mode press keys together. Try it. Print different keywords on the screen. Which one does not print? LETTER The LETTER characters (or OWERTY characters as they are sometimes called) are the bold type letters on each key. They are identical to those on a typewriter keyboard. It is worth trying to memorise these. Do it by lines, and in groups of five. Letter characters may be keyed in when the computer is in the letter mode and the cursor appears in the entered program line, or at the bottom left-hand side of the screen. Certain letters may be entered in the mode as default when there is no keyword on that key, e.g. the digits 0-9 and the full stop[ e] [BREAK] is also an exception. A space Is printed in the mode. 13 Exercise Key in | PRINT | to obtain the mode. Then key in the letters, starting from [1]. What happens with | NEWLINE (ENTER)| and |SPACE |? SHIFT There are 39 SHIFT characters on the keyboard. These may be obtained in the Or modes, 1.e. when Or is on the screen. To obtain these characters or symbols e.g. in our diagram, press the | SHIFT | key and the desired | CHARACTER | key at the same time. Exercise Start keying in the SHIFT characters starting with on the top line of the keyboard. Notice what happens with: EDIT THE ARROW KEYS (^4 | e>) GRAPHICS RUBOUT (DELETE) FUNCTION GRAPHICS There are two types of graphics characters, the characters like Bll as in our diagram below, and the letter and shift characters printed in INVERSE (i.e. white letter on black background) on the screen ( Ia). Exercise To print the graphics characters on the screen key in: 14 Keys to Press What happens on the Screen PRINT E] PRINT PRINT ГЕ | PRINT [К | PRINT PRINT [Эй] PRINT NEWLINE (ENTER) ББЗ at top of screen 0/0 at bottom of screen NEWLINE (ENTER) [3 (clears screen) Notice the mode cursor changes. Note that to come out of the mode, you need to press again, to get the cursor back. To clear the screen press | Repeat the exercise and obtain all the graphics characters. Where no graphics character is printed on the key then the inverse of the shift character is obtained by default. ‘Test this out. INVERSE GRAPHICS These characters are the inverse video letter characters, and are obtained in the GRAPHICS mode, i.e. cursor on the screen, when the desired key is pressed. Exercise Key in the characters as before, but this time only press the letters and not the shift characters when in the mode. What happens when you press |SPACE] ? FUNCTION There are 24 Function characters that are obtained only in the Function mode, when the [F ] cursor is on the screen. The ГЕ |cursor is obtained by pressing the |SHIFT | and | FUNCTION | keys together. Only one Function character may be entered. The mode changes to after entry. To input another Function character we need to get back to the mode again. Exercise Get into the FUNCTION mode and key in all the function characters. Key in - Lr] What happens? Press NEWLINE (ENTER) again to clear the screen. HOW TO OBTAIN THE DIFFERENT CHARACTER TYPES Character Number of To Obtain | To Obtain the Type Chars. the Mode: | Character: mmm f 26 | [E] | лонае SHIFT 39 [K ] Automatic SHIFT CHARACTER LETTER 39 Automatic CHARACTER K] (sometimes) mt = = GRAPHICS CHARACTER INVERSE GRAPHICS Е GRAPHICS CHARACTER SHIFT FUNCTION CHARACTER Exercise Using the above table, obtain all the modes and key in example character types. ALPHABETIC CHARACTER/KEY TABLE The following table locates the letter or number key which provides each character (keyword, function, or symbol) on the keyboard. Use this table when entering programs until you are familiar with the placing of all the commands. An * indicates a non-printing character. BASIC Word Keyword (K), Function or Shift and Key to Press ABS Function G LPRINT Shift S ACS Function S NEW (K) A AND Shift 2 NEXT Shift N ASN Function A NOT Function N AT Function C OR Shift W ATN Function D PAUSE Shift M CHR$ Function U PEEK Function O CLEAR (K) X PI (m) Function M CLS (K) V PLOT Function О CODE Function I POKE Function O CONT (K) C PRINT Function P COPY (K) Z RAND Function T COS Function W REM Function E DELETE Shift Ø * RETURN Function Y DIM (K) D RND Function T EDIT Shift 1 * RUBOUT Shift @ * EXP Function X RUN Shift R FAST Shift F SAVE Shift S FOR (K) F SCROLL Shift B FUNCTION Shift NEWLINE(ENTER) SGN Function F GOSUB (K) H SIN Function Q GOTO (K) G SLOW Shift D GRAPHICS Shift 9 * SOR Function H IF (K) U STEP Shift E INKEY$ Function B STOP Shift A INPUT (K) I STR$ Function Y INT Function F TAB Function P LEN Function K TAN Function E LET (K) L THEN Shift 2 LIST (K) K TO Shift 4 LLIST Shift G UNPLOT Function W LN Function Z USR Function L LOAD (K) J VAL Function J 17 SYMBOLS Symbol Cursor and Key Symbol Meaning K or L, Full stop or dec- imal point (Separate key) š K or L, shifted Full stop. Comma ; K or L, shifted X. Semicolon z К or L, shifted 2. Colon ? К or L, shifted C. Question mark `y K or L, shifted P. String quote iis K or L, shifted О. Quote image ( K or L, shifted I. Open bracket ) K or L, shifted O. Close bracket £ K or L, shifted SPACE. Pound $ K or L, shifted U. Dollar + K or L, shifted K. Plus - K or L, shifted J. Minus 7 K ог L, shifted В. Times / K or L, shifted V. Divide те K or L, shifted Н. To power = K or L, shifted L. Equals > K or L, shifted M. Greater than < K or L, shifted N. Less than © = К or L, shifted К. Less than or equal to > = K or L, shifted Y. Greater than or equal to <> K or L, shifted T. Not equal to “= K or L, shifted 5. Cursor left { К ог L, shifted 6. Cursor down T K or L, shifted 7. Cursor up Т” K or L, shifted 8. Cursor right 18 SECTION C: BASIC BASIC C1: The BASIC Language This book is all about BASIC, which is the world's most commonly used computer language. Just as English is a natural language used to communicate with people, BASIC is a formal language used to communicate with COMPUTERS. Like natural languages BASIC has grammatical rules which, although they are fairly simple, must be strictly followed to ensure that the computer understands exactly what it is being instructed to do. BASIC stands for Beginners All-Purpose Symbolic Instruction Code. It was invented in 1964 in the USA and is a combination of simple English and algebra. BASIC is the language we will use throughout this book to write PROGRAMS. Programs instruct the computer what to do, and the sequence in which particular operations are to be performed. BASIC is a high-level programming language. The instructions we write in BASIC are interpreted by a built-in program into the low-level programming language (the MACHINE CODE) that directly controls the switching of the electrical impulses inside the MICROCHIPS which store and manipulate the data. High-level languages like BASIC are far easier to write programs in than the low-level languages, and the simple language and structure of BASIC was designed to be easy to learn. The Sinclair version of BASIC also has single-keystroke entry of BASIC words, which makes mistakes in spelling impossible. C2: A Simple Program A sequence of BASIC statements is called a PROGRAM. Here is an example of a program: 10 INPUT A 20 INPUT B 30 LETS=A+B 40 PRINT S The simple program above adds two numbers keyed in on the keyboard and prints the results on the screen. A program is keyed (or typed or input or entered) into the computer by you, the programmer, line by line, from the keyboard. Before we key a program in we design it to make the computer do exactly what we want. We first write a program down line by line on a piece of paper. This is called CODING. After coding the program we key it into the computer and RUN it. To RUN it we give the computer a COMMAND to RUN the program to see if it works. It probably won't work the first time, unless it's as 19 simple as our example. A program which doesn’t work as intended is said to contain ERRORS or BUGS. If we have asked it to do something it can’t do, or forgotten to include an instruction the computer will tell us what is wrong and give us an ERROR MESSAGE. If the program runs without error messages but doesn’t do what we wanted it to then it is the programmers’ fault. In either case we need to correct or EDIT or DEBUG the program. We do this whilst the program is in the computer, using the editing facilities of the computer. Editing or revising a program is called PROGRAM DEVELOPMENT. When the editing is finished and the program works we take a LISTING of the program on the PRINTER. We can also SAVE a copy of our program on cassette tape and STORE it so that we can LOAD it back into the computer. The complete exercise of designing, coding, developing and documenting a program is called PROGRAMMING. C3: A Statement This is a BASIC statement: 10 INPUT A A statement is also called a LINE. A statement can: (1) instruct the computer to do something (2) state something A statement is composed of: a line number, e.g. 10 an instruction, e.g. INPUT some variables, e.g. A Statements are either: Executable — those which specify a program action, as with our INPUT A, or Non-Executable — those which provide information for the user of the program. All variables (e.g. A in our example) must be initialised to a start value before being used in a program. In this case the statement: 10 INPUTA tells the computer to request the user to input a value for the variable A from the keyboard. C4: Statement Numbers Each BASIC statement or line must begin with a statement number, as with 20 in this example. 20 INPUT B The number 20 is called a statement number or line number. The statement number is chosen by you, the programmer. It may be any number from 1 to 9999 inclusive. ‘The computer uses the numbers to keep the statements in order. Each statement has a unique statement 20 number. If you use the same statement number twice, the second line will replace the first. Statements may be keyed in via the keyboard in any order. The computer sorts them into the correct sequence. Statements are usually numbered in tens so that additional statements are easily inserted later. For example: 10 INPUT А 20 INPUT B 25 INPUT C (Inserted line) 30 LET S=A+B The computer runs the program in order of statement numbers. C5: Instructions A statement gives an instruction to the computer. In this example it is LET. 30 LETS=A+B Instructions are called statement types because they identify a type of statement. In our example the statement is a LET statement. It tells the computer to let the variable S have a value equal to the sum of the values of variable A and variable B. C6: Numeric Variables A numeric variable is the name given to a storage location which holds a number in the computer's memory. A numeric variable can have a name which is: A letter from A-Z or A letter followed by a number or A group of letters and numbers Variable names must start with a letter. Examples of numeric variables: A NUMBER 1 Numeric variables are used to represent numbers inside the computer. We can give (or assign) different values to a variable. The numbers we give to variables are used in calculations. Variables are symbols or names given to parameters or quantities. They represent the VALUE of the parameter, i.e. the number stored 21 in the named memory location. We can use variable names which remind us of the parameter concerned, but they should not be too long or you will find them tiresome to key in (which is why single letters are usually used). For example, we could use: S — Speed PRICE - Price of fish SUM 1 - Sum of the first set of numbers R3 - Resistor Three In our program the statement 10 INPUT A sets up a variable in the computer's memory with the symbolic name A. We could have called it NUM1, or even FIRSTNUMBER. The statement tells the computer to ask us to input a value for À when we run the program. If we key in the number 3 the memory cell allocated to A will contain the number 3. This value is then used in all calculations involving À until we change its value. In the statement: 30 LETS=A+B S, A and B are the variables in the algebraic equation S= A + B. Š is our ‘unknown’ and will take the sum of the values of A and B. The computer will work out the value of A + B and put the result in the memory cell it has allocated to the variable S. The computer will not let us input LET A+ B = S (it will give us a syntax error), because the variable to be given a value must come first. A + B is not a valid variable name. Variables are so-called because their values can vary or change, according to the values we input, or in the course of a program, when we instruct the computer to do something which causes the value to change. For CONSTANTS, which are quantities which do not change their value, we set up a variable in the same way, by giving it a name and a value with a LET statement and let it keep the same value — a variable that doesn't vary! Variable names may be of any length, but they must start with a letter, and must only contain the alphanumeric characters (the letters A to Z and the numbers @ to 9). They can have spaces included, but this is unwise, as it is easy to key іп PRICEI, for example, when you initialised a variable as PRICE 1. The computer will consider them to be two different variables. The inverse video (white on black) characters also cannot be used in variable names. 22 C7: Strings and String Variables STRING A STRING is a group of characters enclosed by quotation marks. The following are examples of strings: “PETER” “12345” “JANUARY 1ST, 1982” sot “Жы А, “REF:A2” As well as numbers, computers can also handle text or groups of characters. Го define a group of characters as a string, we have to place quotation marks at the beginning and end. This tells the computer, for example, that the string ‘“TOTAL’’ means the characters T,O,T,A,L, and not the numeric variable TOTAL, which is a number. Strings can contain any character which prints on the screen, plus spaces, but a string cannot contain quotation marks, because the computer thinks it has got to the end of the string when it gets to the second quotation mark. Now that you know what a string is, we can tell you that strings can be handled by string variables, just as numbers can be manipulated with numeric variables. STRING VARIABLE A string variable is used to store strings. It consists of a single letter (A to Z) followed by the $ sign. For example: A$, Z$, M$ We allocate (or assign) strings to string variables with LET statements, as with numeric variables. For example: 10 LET A$=‘‘STRING 1" 20 PRINT A$ The memory store allocated to A$ will contain the string ‘STRING 1’ (line 10). When we RUN the program the computer will print the contents of memory store A$ on the screen (line 20), i.e. STRING 1. Note the string is printed without the quotation marks. The string is just the characters inside the quotes. 22 C8: Operators and Operands OPERATORS Operators perform arithmetic, logical or conditional operations on variables or numbers. In our program the line: 39 LETS=A+B uses the two arithmetic operators = and + OPERANDS Operands are the variables or numbers which are manipulated (i.e. operated on) by the operators. In the line: 30 LET S=A+B the variables S, A and B are operands. C9: Format of Statements BASIC is a ‘free format’ language. The computer will ignore extra blank spaces in a statement. The following statements are equivalent: 10 INPUT A 10 INPUT A 10 INPUT A The computer will automatically leave spaces after each line number and a space after keywords. It will list programs with all the other spaces you include between instructions and variables. It will ignore them when you run the program. C10: Keying in a Statement Statement to be keyed in: 10 INPUTA Press If your computer system is set up and ready for use (see Section B1) the cursor will be in the bottom left-hand corner of the screen. You can now key in the first statement. 24 Character or Cursor Keys to What appears instruction Press on the Screen to key in [к] 2 2 19 [к] ж INPUT I 19 INPUT A [z]. A i mera [Z] * NEWLINE (ENTER) Entered line is transferred to top of screen * on Spectrum in CAPS mode PRESS NEWLINE (ENTER) AFTER EACH STATEMENT The |NEWLINE (ENTER)| key must be pressed after each statement has been entered. 10 INPUT A 20 INPUT В 30 LET S =A+B[NEWLINE (ENTER) | 40 PRINTS Pressing the | NEWLINE (ENTER) | key informs the computer that the statement is complete. The computer checks the line for mistakes then transfers the statement to the top of the screen and returns the cursor to the left-hand side of the screen, ready for us to enter the next program line. Notice that the line at the top of the screen now contains the CURRENT LINE CURSOR: This indicates the last program line entered and accepted by the computer. It appears immediately after the line number: 10 [>] INPUT A 25 C11: Correcting Errors RUBOUT (DELETE) The RUBOUT (DELETE) key acts as a backspace, deleting the character symbol or keyword immediately preceding (to the left of) it. As we type in a line we may press the wrong key. For example, we might get: 10 INPUTS where we pressed S instead of A. To correct this we press RUBOUT (DELETE) and we get: 10 INPUT We may now continue and type in A. The horizontal arrow keys move the cursor one character or keyword to the left or right along a line as indicated. For obvious reasons, these keys are also referred to as cursor control keys. To correct an earlier mistake on a line (a) Use the arrow keys to move the cursor to a position immediately to the right of the character to be changed. (b) Press RUBOUT (DELETE) to delete the incorrect character, and key in the correct character. (c) Use the arrow key to return the cursor to the end of the line, if you have more to key in. Otherwise, you may press NEWLINE (ENTER) immediately. It does not matter if the cursor is In the middle of the line. To delete a complete line This can be done by using the > key to get the cursor to the end of the line, if you are not there already, and then using RUBOUT DELETE) repeatedly until the line is completely deleted and just the cursor remains. This is tedious on a ZX81, without the Spectrum’s repeat key, especially on a long line. A better way is: (1) Press EDIT (2) Press NEWLINE (ENTER) 26 If you are keying in the first line of a program and there are no existing lines at the top of the screen, pressing EDIT will clear the line. If there are program lines at the top of the screen, pressing EDIT clears we current line and brings down the program line marked with the cursor. Pressing NEWLINE (ENTER) sends this line up again г. clears (һе current line. Exercises 1 Start keying in the first line of the program. Don’t press NEWLINE (ENTER). Play around with the cursor control keys and RUBOUT (DELETE). Delete the complete line. 3 Key in the first line and press NEWLINE (ENTER). Key in the second line. 4 Delete the second line using EDIT and NEWLINE (ENTER). 5 Кеуіп the second line. Key in the third line to read: 30 LET X =A + B. Press NEWLINE (ENTER) Use EDIT to bring this line down again. Use the cursor control keys to put the cursor to the right of X and delete it. Insert S. Leave the cursor where it is, and press NEWLINE (ENTER) to send the line to the top of the screen. 6 Key in the complete program. N C12: Commands COMMANDS are direct instructions to the computer. They are executed immediately. They do not need line numbers, as they are not part of a program. Commands give us direct control over the computer. Examples are: RUN LIST BREAK SAVE To execute a command, we key it in. If it is a command that is printed, it will appear on the bottom line of the screen. This area of the screen must be empty. Then press [NEWLINE (ENTER). Some commands are executed instantly, without pressing NEWLINE ie i (e.g. BREAK), and are not printed on the screen. Most commands are also used as instructions in programs. Some of the commands that can be used as direct commands are not actually very useful in this role. Equally, some that could be used in programs never are. However, each command has a key role to play in the 27 BASIC language and we will deal with the individual commands as we encounter them in the text. You have already met the NEWLINE (ENTER), RUBOUT (DELETE), < and -” commands, and the mode commands (GRAPHICS and FUNCTION). Together with EDIT, RUBOUT (DELETE) and BREAK, plus the f and $ arrow keys, these are the commands that don’t print, and act instantly. All the others need NEWLINE (ENTER) to be activated. C13: Editing the Program EDIT The EDIT command copies the program line indicated by the cursor at the top of the screen, to the bottom of the screen, replacing any current line. The line brought down can then be edited or changed. EDIT may also be used for entering lines that are similar where only the line number changes: (1) Key in the line. (2) Press NEWLINE (ENTER) - line goes to top of screen. (3) Press EDIT - line copied to bottom of screen. (4) Use RUBOUT (DELETE) to delete the line number. (5) Key in new line number. (6) Press NEWLINE (ENTER) - new line goes to top of screen. The same procedure can also be useful with lines which only vary slightly, i.e. perhaps only the line number and a variable are different. If you can save keystrokes by bringing down a line and revising it, then do so. The technique is as above, but after (5) you must use the cursor control keys to shift the L-cursor along the line and use RUBOUT (DELETE) to erase the variable (or keyword) that needs to be changed. Insert the new character, and press NEWLINE (ENTER). These commands move the cursor in the entered program at the top of the screen from one line to another. This enables us to then copy down any line in the program for editing using [EDIT]. Deleting a line in the entered program To delete a given program line which has been entered and is at the top 28 of the screen just type the line number and press NEWLINE (ENTER). For example: 10 |NEWLINE (ENTER will delete line 10 in the program. You will see it disappear from the screen. C14: Listing a Program on the Screen LIST The program has been entered into memory. To produce a listing on the screen of all lines accepted by the computer key in: LIST NEWLINE (ENTER LIST is a command that prints on the screen. It appears on the bottom of the screen, and is executed when NEWLINE (ENTER) is pressed. LIST N Will list a program starting from program line N. For example, if we key in: LIST 30 NEWLINE (ENTER our program will be listed from line 30. We key in LIST, then the line number we want the listing to start at. If we have a program that is longer than will fit on the screen, we use the LIST (line number) command to display successive screenfuls of the program. If the bottom line on the first screen is 210, for example, we would use LIST 220 to get the next set of program lines. Listing a program on the Spectrum which is larger than a screenful produces a SCROLL? prompt. Answering this with anything other than ‘N’ or BREAK scrolls the listing up so that the next screenful of statements can be seen. C15: Running the Program Our simple program has been keyed into the computer line by line and entered into memory. Let's see if it works. We give the computer the command RUN. 29 RUN NEWLINE (ENTER The RUN command starts execution of a program at the lowest numbered statement. Run is a command and is keyed in. It appears at the bottom of the screen. It will not be executed until [NEWLINE (ENTER)] is pressed. When we do this the program starts operating. The screen will go blank and the L-cursor will appear at the bottom. (This will be a C-cursor if you are using a Spectrum in CAPS (capital letter) mode, using CAPS LOCK as we advised.) The computer is now running the program and asking us to input a number for the variable A. Key in the number and press [NEWLINE (ENTER)] . The L-cursor appears again at the bottom of the screen. The computer requests another number, to be assigned to the variable B. Key in the number | 5 | and press . Our result (the number 8) is printed at the top left of the screen. Notice the message that appears on the bottom of the screen. We can also run the program from a line other than the first program line: RUN N RUN (Line Number) This command starts execution of the program from the specified statement (line) number. RUN 20 will start a program at line 20. Note that when the RUN N command is used all statements before the specified statement number (N) will be ignored and any variables defined in these statements will be considered by the computer to be undefined because it has not RUN the lines. The program will not work and an error message will result. All values of variables are wiped out by the RUN command. We can RUN the program as many times as we wish: Key in [| NEWLINE (ENTER) | again If the program has been run once and the message is at the bottom of the screen, to rerun the program key in RUN. This overwrites the message and pressing NEWLINE (ENTER) starts the computer operating the program. The L-cursor appears to prompt for an input again (C-cursor for Spectrum in CAPS mode). 30 The screen is now blank. We can get the program listing back very easily: Press NEWLINE (ENTER) After running the program, the program listing re-appears at the top of the screen if the NEWLINE (ENTER) key is pressed. The program can now be edited if necessary. C16: Error Messages Our computer tells us it has finished running the program by giving us a message. On the ZX81 this will be: 0/40 at the bottom of the screen. The Spectrum gives an expanded version of the message: 0 OK, 40:1 This tells us that no errors were found and the program finished at line 40 (the last line). The number after the colon can be ignored in most Spectrum error messages, as it refers to multiple-statement lines. We shall not use these in this text. There is one case where it is 2, as we shall see later. These special diagnostic messages appear at the bottom of the screen every time a program is run. If the program does not work a message appears with the form: E/N E is a number or a letter indicating the type of error that has caused the program to stop, and N the line number where the program halted due to the error. The Spectrum adds a message briefly stating the cause of the error. We look up the meaning of E in the list of Error Codes in Appendix II. This helps us to correct or debug the program, since we know what sort of problem has occurred and which program line it happened at. Exercises 1 Run the program on page 19 a number of times keying in different values for A and B. 2 Press NEWLINE (ENTER) to get the listing. Change line 30 to read: 30 LETS-A-«C 31 Now RUN the program. The error message 2/30 (on the ZX81) appears. On the Spectrum we get 2: Variable not found 30;1. So we have a type 2 error and the program stopped at line 30. A type 2 error means we have forgotten to define a variable. We are now using the variable C instead of B, but we have not yet given C a value, and the computer could not complete the operation of line 30 due to insufficient information. Insert a new line: 25 INPUT C and run the program again. It now works. Why did the program originally stop at line 30? Why do we now have to key in 3 numbers to make it work? 3 Add an extra line at the beginning of the program. Key in: 5 PRINT “PROGRAM ADDS 2 NUMBERS" RUN the program, starting from different lines by using: RUN RUN 10 RUN 15 Why do you think RUN 15 does not work? 4 Edit the program to obtain the original version. C17: How the Program Works Line 10 tells the computer that a number must be input and given the name A, (i.e. assigned to the variable A). ‘The computer reads the line and prints an at the bottom of the screen,* reminding us to input a number. The computer will wait until we key in a number. The number is then stored in memory cell A. The computer goes to the next line. Line 20 tells the computer that another number, to be assigned to the variable B, must be input. appears at the bottom of the screen* and the computer waits until we key in a second number, which is stored in memory cell B. The computer goes to the next line. Line 30 tells the computer that a variable 5 18 to be assigned the value of the sum of the variables A and B. The numbers in cells A and B are added 10 INPUT A 20 INPUT B 30 LETS=A+B *This will be a C-cursor if using a Spectrum with the CAPS LOCK facility used, as Spectrum users must do throughout this text to get program listings which appear the same as the ones in the text. Use the CAPS SHIFT and CAPS LOCK keys simultaneously on switch-on, and remember that the C-cursor will appear instead of the L-cursor. We will not mention this again. 32 and placed in cell S. The computer goes to the next line. Line 40 instructs the computer to output the 40 PRINT S value of Š to the screen. The computer looks for the next line. The computer can find no more statements to execute in the program and gives a message 0/40 on the screen telling us that the program finished with zero errors at line 40. The Spectrum gives the same message, in the form 0 OK, 40:1. The computer now waits for more commands. C18: Naming the Program 5 REM “NAME” Programs are named in a REM statement. The program name is enclosed in quotation marks. The program is usually named in the first statement in the program. We need to give our program a name in order to: (1) Differentiate it from other programs (2) Store it permanently on cassette tape (SAVE it) (3) Put it back into the computer from cassette tape in order to run it (LOAD it). The program name can be any combination of characters and any length on the ZX81. On the Spectrum, program names for use with the SAVE and LOAD instructions must start with a letter, and can only have 10 characters in the name. It is sensible to keep the program name short and relevant to the type of program, although some programmers name programs after themselves: “PETER 1” “PETER 2" ete. Programs which undertake various kinds of statistical analysis could be named: "STATS “STATS2” etc, Programs which perform calculations for experiments in the laboratory could be named: "OPTICS З” “FRICTION” “TITRATION” etc. If spaces are used in program names, it is easy to misread them, or forget that there should be a space. If the program name is not one word, we can use an asterisk: “FETTER?” “FOCALLENGTH” etc. ((FOCAL*LEN"' for the Spectrum) 33 Program names and cassette tape codes should be recorded in a DIRECTORY which enables us to access a PROGRAM LIBRARY of programs stored on tape. We need to name our program: List the program and add a line which names the program. For example: 5 КЕМ “SUMPROG” or S REM “PROGI” could be used. We will call our program “АПОПОЕК”, so key in 5 REM “ADDER” 34 SECTION D: SAVING, LOADING AND LISTING D1: Saving the Program on Cassette Tape We need to save programs on to cassette tape (the off-line storage medium the Sinclair computers use) because when the power supply is switched off (or disrupted - variations in the mains supply can affect the computer) the RAM memory and the registers in the CPU are cleared and we lose the program. The memory is said to be volatile. This means we have to key it in again — not too bad for a 5 line program, but a 50 liner will take you an hour! If we had made a copy of the program on to magnetic cassette tape using the SAVE command we could have reloaded it into the computer quickly, using the LOAD command. Tape storage is not the quickest or most reliable method used for off-line storage, but it works, and has the advantage of low cost. The ZX81 reads and writes tape fairly slowly in computer terms, and a large program will take some minutes to LOAD or SAVE. The Spectrum loads programs several times faster. Software (programs) stored on tape is available for use when needed, making it PERMANENT. Software also has to be PORTABLE. Programs we write can be used by other people with the same computer, or software available on cassette can be bought. SAVE SAVE “NAME” The SAVE command outputs the program and variables to the cassette recorder. If the cassette recorder is in record mode then a copy of the program will be made on the tape. Spectrum users please note that the program name for SAVEing must be 10 letters or less. The name can be in either upper or lower case (or a mixture) but exactly the same name must be used to LOAD. It is safer to choose to use capitals only. SAVING THE PROGRAM 1 Check that the cassette recorder is plugged in (or has good batteries). 2 Ensure it is connected to the computer, with the MIC- MIC sockets being connected. See the important Spectrum note below. 35 мы GO Set the TONE control on the cassette recorder to HIGH. Set the volume control on the cassette recorder to 3/4 of MAXIMUM. Insert a new C12 computer cassette tape into the recorder. Short cassettes are more convenient than long ones for our purposes. Run the tape through on FAST FORWARD and then REWIND to ensure equal tension. Set the tape counter to zero and run the tape forward five revolutions (about 20 or 30 seconds). List the program on the screen and printer. Check the program is named (e.g. ‘‘ADDER’’) іп a REM statement. ZX81 Sequence 10 11 12 13 14 15 Type SAVE “ADDER” don't press NEWLINE (ENTER) yet. Press RECORD and PLAY buttons on the recorder. Press [NEWLINE (ENTER) ]. Watch the screen. a) For five seconds it will be grey inversed by diagonal white lines and if the sound on the TV is turned up it will be a monotone. This is the SILENT LEAD IN b) For ten seconds a horizontal striped pattern appears on the screen. This is the program going in. A warbling sound is first heard, then half second pulses. с) Тһе screen goes white and the message 0/0 appears, telling us the computer has transmitted the program to the cassette recorder. The ZX81 does not know whether the recording is successful. We can only tell by later loading the program back in. Stop the recorder Note the counter reading at the end of the program. Run the tape forward five more revolutions of the counter, ready for the next program. Spectrum Sequence IMPORTANT NOTE: YOU MUST ALWAYS TAKE THE JACK-PLUG OUT OF THE EAR SOCKET OF THE SPECTRUM BEFORE ATTEMPTING TO SAVE A PROGRAM. 36 10 Key in SAVE “ADDER”. 11 Press ENTER. The Spectrum will print a message on the screen which tells you to ‘Start tape’, i.e. press RECORD (or record and play, depending on your cassette recorder), and “then press any key'. Do so. 12 Blue and red lines (black and grey оп a black and white TV) will scroll up the border area of your TV screen. This happens twice as the name of the program is recorded. When the program is copied, narrow yellow and blue/black lines roll up the border area. When the recording is complete an *0 OK" report appears on the screen. Stop the recorder. Note the tape counter reading. Your program should now be correctly recorded. 13 On the Spectrum, you can check this without wiping out the program in memory first. Connect the EAR lead from the Spectrum to the cassette player EAR socket. Rewind the cassette to before the start of your recorded program. Get into the E mode, and key in VERIFY, then enter the program name between quotes. Press ENTER and start the cassette on PLAY. The Spectrum displays on the screen any other programs before the specified one that it finds on the tape, printing their names on the screen. 14 When the program has finished playing back, an “0 OK’ message means the program was correctly SAVEd, and *R Tape loading error' means the recording is faulty and you should SAVE the program again. 15 Run the cassette on five more revolutions of the tape counter, ready for the next program. The sequence above assumes a tape counter on your cassette recorder. Without a counter, the process of finding a program is more difficult. To place a voice message on the tape, so that the tape is searched for the voice giving the program name, will prevent the tape being searched automatically by the computer, but it 1s one possible method. If used, you should record your voice (most cassette machines have a built-in microphone) stating the program name several times, then the program name should be spelt out, the name stated again, and some cue statement (“saving starts now’) to let you know that after that point only computer-generated noises exist. This will make finding the program much easier, as the voice cues occupy a larger length of tape than a single statement of program name. The other alternatives are to place only one program on each tape (a bit uneconomical!) or to leave very large gaps between tapes (30 seconds at least), so that you can search using fast forward/reverse and are unlikely to miss the gap. This has the advantage that you can set the computer to search through the tape program by program if you do miss it. Larger programs should be placed if possible on a side of a 37 cassette by themselves. Short length cassettes are available (5 minutes a side) to make this a viable option. Exercises 1 Try a dummy run first. Do not press the recorder keys. Turn up the sound on the ТУ until you can hear a hum. Awful, isn’t it! Key in SAVE “ADDER?” and press NEWLINE (ENTER). (Press a key in response to the message if using a Spectrum). Watch the screen and listen to the different sounds. When the screen clears and the 0/0 message appears (0 ОК, 0:1 оп а Spectrum), key in LIST NEWLINE (ENTER) to get the listing back. 2 Now SAVE the program on to the tape. D2: Deleting the Program from Memory A sure way is to switch off the power - this is not recommended. This should only be done if the computer needs to be re-set because it will not respond to commands keyed in. It is much better to use the command NEW. NEW The NEW command deletes any current program and variables from the computer and clears the screen. We use the NEW command before we LOAD a program into the computer from cassette tape, to erase old programs and data from memory. It is also used to do the same thing, if we have a program in the computer and wish to clear it out to enter another. There is another command that only affects the variables store, and not both this store and the program store, as NEW does. CLEAR The CLEAR command erases all the variables in the current memory. CLEAR can be used as an instruction in a program, as can NEW, but since NEW would merely wipe the program its use would be self- defeating. Try it, if you like the idea of a program that self-destructs! 38 CLEAR is similarly useless in the middle of a program - we would merely have to re-define all variables. With our program, if we RUN it, at the end of the run it will have in the variables store the values of A, B and S. If we then SAVE it, these values are SAV Ed also. In our case this is irrelevant, since the INPUTSs will change them when it is used but often it is useful. We can store data as variables in a program, and not have to re-input values (as long as certain procedures are followed, as we will see later). This enables us to have, for example, a telephone directory stored in variables. We might then use CLEAR to wipe one list, and re-input new data or use CLEAR before SAV Eing the program to send to a friend for his use. CLEAR acts slightly differently on the Spectrum (see page 458), but for our purposes at this point the difference is insignificant. The major function is the same. It is very easy to key CLEAR by accident on the Spectrum, so be careful! Exercises 1 RUN “ADDER”. Enter NEWLINE (ENTER)| to clear the screen. Enter GOTO 40, then press NEWLINE (ENTER). The computer will print the value of 5. Now enter and then GOTO 40 (NEWLINE/ ENTER) again. We then get an error message 2/40 (2 variable not found, 40:1 on the Spectrum) indicating an undefined variable, because the computer has wiped the value of S. We will deal with GOTO in due course. Just follow the instructions for now. 2 LIST the program ‘‘ADDER”’ on the screen. Press and . The listing will disappear and the cursor appears. On the Spectrum, when NEW is followed by ENTER, the screen will go black for a moment then become white, with the words ‘© 1982 Sinclair Research Ltd’ at the bottom of the screen. 3. Press and then [NEWLINE (ENTER) ]. What happens? Why? 4 Key in the first line of the program and press NEWLINE (ENTER). Switch off the power supply (by pulling out the jack- plug). Switch it on again (by re-inserting the jack-plug). What happens? 5 Re-enter ‘‘ADDER’’. D-3 39 D3: Loading the Program from Cassette Tape LOAD “NAME” The command LOAD “МАМЕ” waits for the cassette to play the portion of tape with the program called “NAME” and copies the program, with its variables into the computer’s memory. This means that we can start the tape, give the command LOAD “МАМЕ”, and the computer loads nothing into its memory until the signal it recognises as NAME appears on tape. We can thus search a tape for a program. The Spectrum will print on the screen the names of any programs it finds on tape, before it encounters the specified program. LOAD “” The LOAD “” (nothing between the quotes) command LOADS the first program it finds on the tape. N LOADING PROCEDURE ON THE 4Х81 Place the tape with the desired program in the cassette player. Position the tape via the counter to just before the location of the required program. Clear the computer’s memory using the command if there’s a program in memory. Set the TONE control on the tape recorder to nearly Maximum (High), and the VOLUME control to % Maximum. Key in LOAD “ADDER” or the appropriate name. Don’t press NEWLINE (ENTER). Depress the PLAY key on the cassette recorder. Press NEWLINE (ENTER). A thin diagonal pattern will appear on the screen with a single tone sound. The pattern changes to broad horizontal stripes with thinner diagonal stripes and half second sound pulses are heard as the program is loaded in. The screen clears and а 0/0 message indicates the loading is a success. STOP the recorder. 40 10 11 COND л 10 11 12 LIST and RUN the program. Remove the tape when finished. LOADING PROCEDURE ON THE SPECTRUM Place the tape with the desired program in the cassette player. Position the tape via the counter to just before the location of the required program. Clear the computer’s memory using the NEW command if there’s a program in memory. Set the TONE control on the tape recorder to nearly MAX (High), and the VOLUME control to % MAX. Key in LOAD ‘‘ADDER’’, but don’t press ENTER yet. Press the PLAY button on your cassette recorder. Press ENTER. When the Spectrum has found a program it will scroll blue and red bands of colour up the border area. The name of the program will be printed to the screen and then the blue and red lines repeated again. If the correct program has been located, then it will LOAD with a finer set of blue and yellow lines scrolling up the border area. If not, the border area will flash blue and red alternately as it carries on to the next program on the tape. When the program is correctly loaded, the phrase: 0 OK, 0:1 will appear at the bottom of the screen to indicate that all is well. Stop the recorder. LIST and RUN the program. Remove the tape when finished. CAUSES OF FAILURE TO LOAD 1 3 Volume too low. Volume too high. Tone too low. These indicate that the program has been played at the wrong settings. New volume and tone adjustments will have to be made. Some indications of these problems are visible on the screen display of the ZX81, although systems vary in their response. Appendix IV has a procedure for adjusting tone and volume settings for the ZX81, as well as some general hints on tape use. Experiment and get to know the patterns produced during LOAD on your ZX81. 41 4 Loading started in the middle of the program. If a mistake has been made with the start position, rewind the tape completely and let the computer search for the program name. 5 The program is not on the tape. Check your directory, and the writing on the cassette. 6 Тһе program name is incorrect. Try again, making sure you have spelt it correctly in the LOAD instruction. If you fail again, run through the tape using the LOAD ““””' command. This will load the first program each time. Stop the cassette player after each load and LIST the program to check. (This is not necessary on the Spectrum.) If it's not the program you want, repeat for the next program on the tape. The Spectrum will print the name of all programs оп tape if you use a LOAD “ZZZ” instruction, i.e. a name that does not exist as a program name. 7 Pick up from stray electromagnetic fields. This will show as violent interference on the screen, distorting the patterns together with excessive hum on the sound. It could originate from the ГУ itself, feedback between the recorder and the computer or an external field. Switch off any radio that is in the vicinity. Take out the jack-plug from the MIC socket of the cassette player, as this will break the feedback loop that can exist between the computer and the cassette player. The Spectrum has fewer LOADing problems than the ZX81. It will accept a much greater variation in both the volume and tone of the signal. However, it is worth noting that if there are great differences between the recorder the tape was recorded on and the one it is played back on (variations in tape-head azimuth is often the main source of the problem), then LOADing can be almost impossible, even on the Spectrum. As we noted at the beginning of the book, the Spectrum, unlike the ZX81, offers a choice of upper and lower case letters. Ensure that if you have used lower case ones in the program's name, then you use them again in the LOAD “ххх” command. The same applies if you use upper case letters to name a program. Thus, a program named “MATHS” will not LOAD with the statement: LOAD ‘‘maths’’. Some further information concerning the use of cassette tapes, and advice for the ZX81 if problems are encountered is given in Appendix IV. Exercises 1 Load the program “ADDER”. LIST and RUN it. Delete it from memory, using NEW. Try loading it with different volume and tone setting. Estimate the volume and tone ranges for which it will not load. If you have a ZX81, you can do this by watching how the screen 42 patterns change when you change the settings while the program is loading. Read Appendix IV. D4: Listing the Program on the Printer LLIST LLIST lists the program currently in the computer memory on the printer, starting from the first program line. LLIST N LLIST N lists the program on the printer starting from line N. We can stop the listing by pressing (BREAK needs CAPS SHIFT on the Spectrum). This stops the listing with an error message D/line number on the ZX81 and D BREAK - CONT repeats 0:1 on the Spectrum. It is important that you keep a listing or printed record of all the programs you write or use. The listings are a great help in debugging programs (both under development and if there are problems discovered later). We can key the program back in from this listing, if necessary. Printouts also form part of the documentation for a program and should be pasted into a notebook. Printed records of program results can also be kept using the COPY command. Exercises 1 LLIST the program ‘‘ADDER”’ on the printer. 2 ‘Try stopping the listing with the BREAK key. The listing cannot be continued by pressing CONT (try it). On the Spectrum, despite what it says, this doesn't work. The screen just goes blank. Don't worry. Press BREAK again. 3 List the program on the screen. Use the COPY command to list the program on the printer. What is the difference between the two listings obtained with LLIST and COPY? 43 D5: Program Libraries and Directories LIBRARY A collection of programs stored on cassette tape. For example: COMPUTERLAB PROGRAM LIBRARY or Your own program library. Notice that programs can also be stored on magnetic discs and im ROM memories. DIRECTORY The list of program names in the library together with important information about them. Another name for a directory is CATALOG. You should keep, in your notebook, or a special book, a directory of all programs you have entered and saved on tape. This will seem a bit pointless when you only have a dozen or so, but you will appreciate the need to be systematic when you accumulate a large number. PROGRAMS YOU WRITE Each program you write should be Named. Saved on a cassette tape. Listed on the printer. Documented. Catalogued into the Directory of your own program library. Gm wm G3 N = DOCUMENTATION The complete collection of information about the program or file, written on paper. The information should include: 1 What the program does. How it does it. A listing. A flowchart. How to use it. When it was written and by whom. Q3 Gr мы CS N 44 We will introduce flowcharts in Section G. DIRECTORY LAYOUT A typical layout for the Directory Section of your notebook would be: Program Name: MOONLANDER Cassette Name: GAMES 3 Locatton: 100-120 Program Length: 30 lines Date Created: 18.5.82 Author: PAUL NIXON Function: Lands a spaceship on the moon WRITING ON THE CASSETTE There is a label on each side of the cassette. Write on each side: 1) Cassette name or code. 2) Date. 3) Program names as they are copied into it. Make sure these are correctly spelt! Your directory should provide you with the more detailed information, such as precisely where the program is to be found. 45 SECTION F: IMPROVING THE PROGRAM E1: Adding Comments REM The REM statement is used for adding comments to a program. All REM statements are ignored by the computer when the program is RUN. These comment statements are for the users’ benefit only. They contain information in the text of the program which explains what the program is doing. For example: REM **THIS PROGRAM ADDS TWO NUMBERS KEYED IN AND PRINTS THE RESULTS** Notice the use of the asterisks to separate the text from the instruction. 100 REM ** END OF PROGRAM** The complete program including all REM statements appears on the screen or printer when using the LIST and LLIST commands. Our saved program so far looks like this: 5 REM “ADDER” 10 INPUTA 20 INPUT B 30 LET S=A+B 4) PRINTS Let us add some additional REM statements: 6 REM **THIS PROGRAM ADDS TWO NUMBERS KEYED IN AND PRINTS THE RESULT** 60 REM **END OF PROGRAM** Key these extra statements in. LIST the program and RUN the program. Do not worry about the line numbers not being in intervals of 10. We will renumber the program when we have added all the extra lines. E2: Using the Print Statement PRINT In our simple program we will use the PRINT statement: a) To print messages and instructions to the user on the screen: 7 PRINT “INPUT TWO NUMBERS" The message INPUT TWO NUMBERS is a string, and will be printed without the quotes. 46 b) To print the numbers keyed in and the result: 40 PRINT A; ‘‘ + ’’;B;‘* = ?°;5 A and B are the names of the variables to which the numbers keyed in are assigned, and S is the variable that stores the sum of A and B, i.e. the result. Variables do not need quotes to be printed. The semicolons (;) tell the computer that we want close printing, with each print item (character or variable) directly after the last, with no spaces between. The inverted commas (quotes) enclosing the symbols + and = means we want those symbols printed. c) To leave spaces between lines printed on the screen: 8 PRINT The PRINT instruction used on its own prints an empty line on the screen. Note that we have changed line 40 from what it was previously. Our program now looks like this: 5 КЕМ “ADDER” 6 REM **THIS PROGRAM ADDS TWO NUMBERS KEYED IN AND PRINTS THE RESULT** 7 PRINT “INPUT TWO NUMBERS” 8 PRINT 10 INPUT A 20 INPUT B 30 LET S=A+B 40 PRINT А‘ + ‘В; = > 58 60 REM **END OF PROGRAM** Key in the new lines and RUN it. E3: Adding a Loop GOTO N The statement GOTO N transfers program execution to the specified line number, N. For example: 50 GOTO 7 When we insert line 50 into our program we can see that, after printing the result on the screen, line 50 sends the computer back to line 7 to execute the program again from that line, and as soon as the computer reaches line 50 again it is sent back to line 7 once more. We have constructed a LOOP. The program is going to carry on looping forever unless we can pull out of it. 47 Our program now is: 5 REM “ADDER” 6 REM **THIS PROGRAM ADDS TWO NUMBERS KEYED IN AND PRINTS THE RESULT** 7 PRINT “INPUT TWO NUMBERS” 8 PRINT 10 INPUT A 20 INPUT B 30 LETS-A-«B 40 PRINT A;" &'B;"UeCUNS 50 GOTO 7 60 REM **END OF PROGRAM** Key in line 50. RUN the program. When you are tired of inputting numbers, read on. E4: Stopping the Program We need to know how to get out of the input loop between lines 7 and 50. The program will wait for an input of a number at line 10 INPUT A. The cursor will appear on the screen. To pull out or stop the program at this stage key in [STOP | [NEWLINE (ENTER)]. STOP is a command we input directly, like RUN. STOP On the ZX81 the STOP command stops a program with the message: D/line number, and on the Spectrum we get H STOP in INPUT (Line number):1. The line number refers to the program line the computer was executing when it was stopped. Our program will give D/10 as the message (H STOP in INPUT 10:1 on the Spectrum). We can cancel the STOP command and continue the program with the CONT command. CONT The CONT command used after the STOP command will continue the program from the line the program was stopped at. 48 Keyin ICONT | INEWLINE(ENTER)| to continue the program. Note the Spectrum prints CONT in full as CONTINUE. Exercise Run the program “АОПЕК”. STOP the program when the first | L | cursor appears. CONTinue the program, and input a value for A. STOP the program when the second cursor appears. Note that the line number is different in the message that appears on the bottom of the screen. CONTinue the program. E5: Testing for a Condition In a program we can make decisions which will affect what the computer does next. A decision is made on the basis of whether a CONDITION is true or false. CONDITION A condition has the form (X) (condition) (Y) where X and Y are numbers, variables or expressions and the condition is a conditional operator. We shall use only the = (equality) operator for the moment. The following are all conditions: X=Y A = 23 B = 2*3 Conditions are tested and the next action determined by the result of the test with the IF and THEN statements used together. IF - THEN An IF - THEN statement has the form: IF (condition) THEN (instruction) For example: IF А = B THEN PRINT “EQUAL” IF A=@ THEN LET A= 3 The instruction can be any valid instruction. The statement means: IF (the condition is TRUE) THEN (perform as instruction). IF (the condition is FALSE) the computer ignores the instruction after THEN and goes to the next line of the program. 49 In our simple program we can use the IF — THEN statement to insert in the program a conditional test which will stop the loop, without using the direct commands which we used in the last Unit. To STOP the program in the same way as with a direct command we can insert another line: 15 IF A«9 THEN STOP This tells the computer that IF A = 0 (if it is TRUE that A is equal to 0) THEN it should STOP. IF A is any other value (if it is FALSE that A = 0) it ignores the THEN STOP instruction and moves to line 20. Enter this line into the program. RUN the program. Enter different non-zero values for A to see that if A 1s not zero then the program continues as before. Enter .000000001 to see that only if A is exactly zero will the STOP instruction be executed. Input 2 for B, and notice that the result is given as 2. This is due to the fact that calculations are only performed to a certain degree of accuracy. Enter .0000001 for A, and input B as 2. The computer returns 2.0000001 as the value of S- the number is within the limits of accuracy. Now enter 0 for A. The program will stop, just as when we entered STOP as a direct command. Notice, however, that the message at the bottom of the screen is different. We get the message 9/15 on the ZX81 (a STOP statement, 15:2 on the Spectrum).* The message is different because STOP in a program means “f the CONT command is received, proceed with the next program line', since if it continued with the same line it would just STOP again! As a direct command, however, STOP means ‘if the CONT command is received, start with the same program line', so that the computer does not miss out a program line. Now we have some extra control over the program, but it is still not satisfactory. We used IF A - 0 because in this program it is not a value we are interested in seeing added to B (a value used in this way is known as a DUMMY or SENTINEL VALUE - a value just used as a signal to the computer which would not need to be entered in the course of normal inputs). This stops the program and we can continue it, but the program just goes back into the loop. We need a method of proceeding out of the loop to end the program, or continuing with more program lines. We can do this with a STRING CONDITION. The conditional operators can also be used to express relations between strings - either string variables or simple strings. We insert the following lines: 30 PRINT “RUN PROGRAM AGAIN ?(YES/NO)" 55 INPUT A$ 56 IF АЗ - ““ҮЕ58” THEN, GOTO 7 “Оп the Spectrum, the statement after the THEN іп an IF- THEN statement is treated as the second statement in the program line. This is why we get 15:2, meaning line 15, statement 2. This is the only instruction used in the main text of this book (before Unit W2) where the statement number will not be 1 in an error message. 50 When the program gets to line 50 it will print out the message, and then put the cursor at the bottom of the screen. Because it has been told that a string input is to come, the cursor has quotes either side: "[L]". There is no need to type quotes. Whatever characters are typed in will be stored as A$. The string is entered by pressing NEWLINE (ENTER) after keying in the characters. Line 56 tells the computer to check if the characters in A$ are the same as the characters of the string ‘‘YES’’. If they are it goes to line 7. If they are not the program will continue to line 60. Notice that any string other than “YES” will cause the program to continue to line 60. Exercises 1 Delete line 15 in our program, which we no longer need. Insert the new lines 50, 55 and 56. 3 RUN the program. Enter “YES” in response to the string input cursor and see that the program loops back to line 7. 4 Next enter “МО” to see that the program goes to line 60 and gives the message 0/60 (0 OK, 60:1 on the Spectrum). Run the program again. This time enter anything other than ‘ҮЕ’ or “МО”, to see that the program goes by default to line 60 if anything other than ''YES"' is entered. 5 Experiment with the string input. What happens if you press NEWLINE (ENTER) without inputting anything? What happens if you try to key in quotes around the string? 6 LLIST the program on the printer. The development of our program is complete, and we have run it to see that it works. It remains to renumber the lines, and this is easier to do if we have a listing. E6: Final Edit and Saving Our program ‘‘ADDER”’ is complete and works. We need, however, to renumber the lines. The procedure for this is as follows: 1) Using the listing from the printer, renumber the statement lines in tens at the side of the old number. You can also count the number of lines in the program on the screen display, and multiply by ten to get the new highest line number. For our program, this will be 120. 2) a) List the program on the screen. b) Usethe ^4 and | cursor control keys to bring the current line cursor to line 60 (the bottom line of the program). c) Press EDIT and pull line 60 down to the bottom of the screen. d) The new HIGHEST line number is 120. e) Change 60 to 120. 31 g) h) J) Press NEWLINE (ENTER). Line 60 remains, but it 1s duplicated by the new line 120. Delete the old line 60 by entering 60 and pressing NEWLINE (ENTER). Change each line number in this way, going from highest to lowest. Lines that contain other line numbers must have these changed to their new numbers. In our program we must remember to change line 56 to: 90 IF A$=‘‘YES’’ THEN GOTO 30 where 3@ is the new line number corresponding to the old line 7. Rename the program ‘‘ADDER2’’, at the same time as you change the line number of line 5 to 10. This program is different from the original version, and must be given a different name both for our reference, and the SAVE and LOAD operations. Run the program to check that it still works, and that we have all the lines, with any GOTO (line number) statements correctly renumbered. LIST and LLIST the program. SAVE “АОПЕК2”. Write the name of the program on the tape cassette, along with the tape counter readings. Put details of the program in your directory. Stick the listing of the program in the notebook you are using for documentation. 52 SECTION F: A GAME INTERLUDE F1: The Program Library In addition to the many programs and subroutines in the main body of the text, there are additional applications and games programs in the Program Library (Appendix VI). Our main objective is to enable you to write your own programs, and the programs in the text have been used to illustrate the use of techniques. Some are functional (do something significant) and some are just illustrative. You don’t have to key all the programs in the text into the computer, but you must understand them. However, you should key in all the shorter programs since it’s important to see how different types of program operate in practice. Analysing the longer programs is vital, even if you don't key them in. The use of flowcharts (to come in Lesson G) is helpful for this. There are also suggestions for programs you should write, to get practice in writing programs to perform tasks, after units dealing with specific techniques. The programs in the library are examples of applications and games programs, plus a number of subroutines for some of the manipulations commonly required in programs. You can key these in at any time if you want to see how the program works, find the program useful, or want to play the game. Once keyed in you can SAVE them on cassette and LOAD them back in quickly. None of the programs are very long, since it is difficult to analyse long programs, and this is what we want you to do. Keying in a program from a listing doesn’t teach you anything about programming, nor does running it. Writing or modifying a program does! We hope you find the programs entertaining or useful, but please treat them as a source of ideas and illustrations about programming, not as a fixed set of optimum solutions. Programs can always be improved! Be careful when keying in programs, especially if you don't understand how they work. (It might be better to work this out first - because, to labour the point, that way you'll learn something.) The S-cursor will mark some errors in lines for you and stop you entering them, but there are always other problems you can introduce. Check through your listing for errors and missing lines (surprisingly easy to do, even with numbered lines) before you run the program. You must also be careful to check that any necessary alterations have been made to the program if you are going to run it on a Spectrum, as noted in Unit W2. These are mostly minor but can be crucial. F2: A Game to Key In You have now spent a lot of time working through the essentials of your computer system and its BASIC, and you probably have the feeling 53 that thus far you haven't seen anything to persuade you that computers are particularly exciting machines. Far from being impressed by their capabilities, you may well be thinking, ‘What’s so good about a computer if you need to do all this to get it to do something that I could do in my head when I was six?’ Well, the following program may not be earth-shattering, but it does in fact reveal a fairly complex set of computer operations, as well as providing amusement. The program is called **BUG"' and it enables you to play a game that consists of dropping bricks from a height to squash the 'spider' (an asterisk) scurrying along below. If you have a militaristic or SF streak in your nature, or are an arachnid lover, feel free to change the name to “BOMBER” or whatever (in line 5). Whether you will enjoy it more by pretending you're napalming Venusians is your affair. It won't alter how the program works! To play the game, however, you first have to key it in. You won't understand at this point how it works (and won't for a few chapters yet), so you have to rely on keying it in exactly as listed. Like all the programs in the text, this one will look somewhat different on the screen or in a printer listing, since for clarity we have not reproduced the printer listings exactly, since printouts tend to contain broken words (when one line on the screen is full and the computer runs on to the next) and other possible confusions. Check each line carefully before you press NEWLINE (ENTER), and pay special attention to the punctuation. Notice that there are 2 spaces before the asterisk (spider) in line 50, and 3 spaces either side of the <=> (brick dropper/intergalactic space hod) in line 60. If you have any difficulty finding the right modes and keys for the characters you need, refer to the list in Section B (ZX81) and Unit W1 (Spectrum). It is very easy to end up typing a keyword instead of inputting it directly when you are keying in a listing (typing T,O instead of inputting TO, for example). If you do this it is not clear why you get the cursor indicating an error, since the line /ooks the same as the listing, so be warned. ZX81 Users! Notes The graphic character in line 160 is an inverse asterisk, (SHIFT B in Graphics mode) and in line 190 the characters are the SHIFTed graphic on the T key, the asterisk again, and the НІЕТеа graphic on the Y key. The comments in square brackets are intended to be helpful, not to be entered! Spectrum Users’ Notes Line 60 has an inverse video asterisk. Го get this, key CAPS SHIFT and the 4 key to get INV. VIDEO. Then input the asterisk. Use CAPS SHIFT and the 3 key to get TRUE VIDEO, i.e. normal black on 54 white, back. If you don't return to normal video, the quotes will be in Inverse, and so will everything after it. Line 190 has the unshifted G mode graphic on the 6 key, and then the CAPS SHIFT graphics on the 8 key and the 6 key as the graphics string. 5 КЕМ "BUG" 10 LET 5-0 20 LET B=10 30 FOR N-1 TO 12 40 LET C23 L SQ PRINT AT 2O»C-2;" +" [2 Spaces #] 60 PRINT AT (ЗЕ-2;" <=> и [3 5р, =>, 35 Sp] 70 IF INKEYS ="6" THEN GoTo 150 80 LET B=B+(3 AND INKEY$ -"&" AND B<28)-(3 AND ІМКЕҮФ = "=" AND B»3) 90 LET C=C+ INT ( ЕМО *2+1) 100 IF C<30 THEN GOTO 50 110 CLS 120 NEXT N ie ERE np 1g RER "9! — DSCUREDIEM % SRATI 140 STOF 150 FOR F=4 TO 20 ЕТЕР 4 160 FRINT AT Е,Б+1;"Ш" AT [Inverse %1 FsB*1;" " 170 NEXT F 180 IF E+1 <> C THEN GOTO 50 Г <> іс one character] 190 PRINT AT 20»C-1; "EF"; AT 2130-2; "SPLAT" 200 CLS 210 LET S=54+1 220 GOTO 120 When you've got it all keyed in, LIST it to check it through again. Check the first screenful, then (on a ZX81) LIST 170 to get the rest of the program (with a line that was on the first screenful to keep your place). LLIST it on the printer. Key RUN then NEWLINE (ENTER) to play. The keys 5 and 8 move you left and right respectively across the top of the screen. ‘They are chosen for the direction of the arrows printed on them. Key 6 will drop the brick. If you hit the spider it goes splat and you score a point. You have to hold the keys down to ensure that the computer will read the keys and perform the right operations. This is because it reads the keys only once in each pass through the loop (lines 50 to 100), апа might miss the input otherwise. When you’ ve played the game a few times, SAVE it on to tape and catalogue it. 55 | ——————— ph wrt - ot 740 | 7% 03: 2. -— ` 1484 4973 ^c, з I E á ja % “4: 5 i э pis * Ж | c ° m L 474 f ° I TL à é ” ' / F | L 1% и. i í í А б =, i ` Wf i r ; 4 ъ PART TWO ESSENTIALS OF BASIC PROGRAMMING SECTION G: PROGRAMMING METHODS I G1: Programming Now that you can operate your computer and have written a short program we must look in greater detail at the activity we call PROGRAMMING and study how: COMPUTERS SOLVE PROBLEMS To enable them to do this we engage in the two main activities of programming: 1 PRODUCE THE METHOD FOR SOLVING THE PROBLEM 2 PRODUCE A WORKING PROGRAM The method for solving our problem is called an ALGORITHM. An algorithm 1s like a cookbook recipe, and is written down in steps in a brief English style we call PSEUDOCODE, and the method by which we arrive at the recipe is called STRUCTURED PROGRAMMING. We break the problem up into smaller sub-problems or sub-tasks in a step by step, modular fashion, starting from the simple initial statement of the problem and working down to lower levels of greater complexity (i.e. in a TOP DOWN manner). As we refine our problem our steps become more like the operations the computer can perform. Our final description of the lower level of the algorithm will be in terms of the control and other structures of the language. To help us produce the algorithm we use STRUCTURE DIAGRAMS. The simplest of these is a TREE diagram. The pseudocode description of the algorithm is easily written down from the descriptions of tasks in the tree diagram. We cannot key the pseudocode description of the algorithm into the ZX81 or Spectrum because it will not understand it, and there is no means of doing it anyway. We have to translate each section of the pseudocode into its equivalent in the BASIC language, which the computer understands, to produce a PROGRAM. For the computer to be able to run the program successfully and produce the results we require, there has to be a LOGICAL FLOW to the program. This is often difficult to see from the structure diagram, and so we use another diagrammatic technique to illustrate the flow of control through the program, i.e. determine the order in which the program modules or sub-programs are processed and the order of coding the specific instuctions within a module. This technique uses FLOWCHARTS. These are important for documentation purposes and are in common use. We will describe them shortly. 59 Producing a working program involves running and DEBUGGING (correcting errors in) our first effort. We then have to TEST the program with sample data and finally DOCUMENT it. In this first section on methodology we shall consider problem solving and coding the algorithm in BASIC in more detail. You will see that the first half of the activity we call programming is LANGUAGE INDEPENDENT. Having produced our problem solving method - the algorithm — we can code it into any computer language we wish. We need to know the language thoroughly and how the fundamental programming structures we have used in the algorithm - decisions, loops, subroutines, subprograms, functions — can be implemented in that version of the language which runs on the computer we are going to use. In this book we are using the ZX81 or Spectrum computers. The versions of BASIC are slightly different. All that this means is that whilst the algorithms to be coded for both machines will be the same, the final programs may be slightly different. Our algorithms and their representation in pseudocode and flowchart form are thus PORTABLE from one machine and language to another. Good coding habits are also important. There are good and bad ways of turning the solution to a problem into a working program. Style, presentation, ease of understanding, modularity, efficiency are all important. Throughout our book the emphasis will be on correct problem solving techniques and good programming practice, while you gain a thorough knowledge of BASIC. Here is our first rule of programming: PROGRAM CORRECTLY FROM THE START Remember - bad habits die hard! The material in this Section may initially appear dense and difficult to follow. Work through the text carefully, and refer back to this Section as often as you feel necessary, when each of the topics covered in the following Sections (dealing with the essential groundwork of the BASIC language) has been introduced. The exercises given in the text should be used to put into practice both the specific techniques involved and the general approach to programming presented here. G2: Problem Analysis Producing the algorithm, or method of solving the problem, is often the most difficult part of programming because it involves the most work. From the start careful planning and organisation are absolutely essential. The task is simplified when a structured design method is used, coupled with a diagrammatic representation of the algorithm 60 using a structure diagram or flowchart. The actual coding of the program in BASIC using the available language instructions is then a straightforward matter. To produce the Algorithm we must: STATE THE PROBLEM RESEARCH THE PROBLEM DESIGN THE ALGORITHM DESCRIBE THE ALGORITHM IN PSEUDOCODE AND FLOWCHART FORM = һі = = A GO м м Let us now consider each of these steps. 1.1 State the problem fully 1.1.1 STATE THE PROBLEM 1.1.2 UNDERSTAND WHAT IS TO BE DONE To solve any problem we must know what the problem is and what is to Бе done. We later work out how to do it. A complete statement of the problem should include: (i) What information or data is to be input. (i) What answers or results are to be output. (uni) What operations аге to be performed on the data. At this stage a precise description of (111) may not be available. EXAMPLES Problem: Write a program which will print out the sum and average of five numbers input at the keyboard. Problem: Using the computer produce a telephone directory to contain up to fifty entries, which may be updated and assessed in an enquiry mode. In the first problem the input data, output data and operations are easy to see. The second is much more complex and needs more researching and information. What we are trying to do in 1.1.1 and 1.1.2 is to initially specify the problem as exactly as possible. When we analyse the problem further we may have to go back and ask for more information 1.e. a more detailed specification. 61 1.2 Research the problem 1.2.1 RESEARCH AND ANALYSE THE PROBLEM TO SEE HOW THE COMPUTER CAN HANDLE IT 1.2.2 IDENTIFY ALL FORMULAE AND RELATIONS INVOLVED 1.2.5 IDENTIFY ALL DATA INVOLVED Here we start to determine how the computer may solve the problem. We need to find out and write down: (1) What formulae and expressions are to be used. (п) What kinds of data are involved - numeric, string, etc. (ui) What functions are involved. (iv) What is input and output data. (v) What is the form of this data. (vi) How much data there is. (vii) What processing is to be done and how many times. It is useful at this stage to start to create a data table (a table of variables, constants and counters), to record how we are going to store the data. Other questions we will ask when we are a little more experienced are: Have I solved a problem like this before? Can I use my solution or modify it? Has anyone else solved it? Where can I find their algorithm or program? ALL THE FACTS OBTAINED FROM RESEARCHING THE PROBLEM SHOULD BE JOTTED DOWN We can now begin to design the algorithm in a structured manner. 1.3 Design the algorithm using structured methods 1.3.1 BREAK THE PROBLEM DOWN INTO SUB-PROBLEMS 1.3.2 USE A STRUCTURE OR TREE DIAGRAM TO HELP 1.3.3 CLASSIFY MODULES OR PART MODULES AS — INPUT — PROCESSING – OUTPUT USE FUNDAMENTAL CONTROL STRUCTURES SET UP A DATA TABLE REFINE THE ALGORITHM UNTIL CODING INTO BASIC IS AN OBVIOUS EXERCISE кі = = 92 G3 Go HD Qv > Structured programming means designing the algorithm in a top 62 down, modular fashion, with step by step refinement of the solution starting from the single statement of the problem which we place at the highest level. We break the problem into sub-problems at successive lower levels. Each sub-problem or module is one that can be solved individually. Structure diagrams or tree diagrams are useful as a representation of this refinement process. G3: Structure diagrams These enable us to break down the problem into distinct tasks and sub- tasks which eventually become simple enough to be coded directly in BASIC instructions. One form of these diagrams is TREE DIAGRAMS. The tree diagram has its trunk at the top of the page. We call this BOX 1 and give it the title: TASK TO BE DONE. We could have called it ‘problem to be solved’. For example, make a cup of tea or find the average of five numbers. We next break down the task into things to do. These are sub-tasks and each has its own box. For example: BOX 1.1: First thing to do BOX 1.2: Second thing to do Each sub-task is broken down into further sub-tasks: 1.1.1, 1.1.2 etc, each with their own boxes, the things to do placed in them becoming progressively more exact and simple. Breaking down a task into a tree diagram: first level second level її 1.2 145 FIRST THING SECOND THING LAST THING pO TO DO third level ERE И Е. 1.2.1 1.2.2 3.253 4,2,2 L. 39 Sub- Sub- Sub- Sub- Sub- Sub- Sub- task task task task task task | task The sort of programs you will start to write in BASIC are sequential, that is to say things are done one after another, so you need to be able to indicate that the program should first do one thing, then a second, then a third . . . and so on. You do this by drawing the boxes which 63 contain the tasks to be done in a straight line across the page next to each other for example: The numbers contained within each box identify where the box is placed on the tree. Take for example: The first digit shows it comes from the first level 1 ‘What is to be done’. The second digit ‘2’ shows it has come from the second level box 1.2 ‘Second thing to be done’. The third digit ‘3’ shows this box is the third sub-task in the sequence derived from which in turn is derived from . Into the boxes go brief statements of the actions needing to be performed. These are general statements at the top of the tree, e.g. ‘Get Sum of numbers’, but become more specific at each lower level, so that ‘Get Sum’ is broken down in the operations needed to produce the result ‘Get Sum’, e.g. ‘Input first number’, ‘Input second number’, ‘Add the two numbers’. Finally the instructions become detailed enough to form our English language ‘pseudocode’ which can be written out, ready to be translated into BASIC instructions. AN EXAMPLE OF TREE DIAGRAM DESIGN Here is an example to try out. Suppose we have a robot with arms, legs and eyes which we want to program to make a pot of tea. Our major task for the robot is: 1 Make а Pot of Tea This can be broken down into sub-tasks which we put in order across the page: 1 МаКе а Ров of Tea Les Put Water in Pot Each of these sub-tasks is still far too complicated for our robot to do. We must break the problem down further. Breaking down 1.1 into sub- tasks we get: те Ме 1.1.2 11.3 Fill the Kettle Plug in Kettle Wait Until with Water and Turn On Water Boiling The robot also needs to be told how to fill the kettle so we break this down as: 1.2.1 Fill the Kettle with Water у 9000. Т МИК: Wait Until Full L. L La L Put the Kettle Under Tap On the next page is a complete tree diagram. Certain things are still wrong with this algorithm for our robot, but it does show you how a problem can be broken down. G4: Classifying Program Modules Most computer programs involve: INPUT PROCESSING and OUTPUT activities. As we are designing our programs and forming modules, it becomes evident from our pseudocode description of the algorithm which of the above functions the modules should have. Depending on the problem and the result of our algorithm design, modules may be separately 65 99 T La Boil Water Put Tea the Pot Loan әш, Wait Get Tea Until Pot Water Boiling i E: Put Water into the Pot Lk ЖЕ! Take the Pot to the Kettle designated input, processing, and output functions or may have these functions nested as sub-modules. Module 2 PROCESSING Module OR Module І Module 2 PROGRAM G5: Control Structures PROCESSING OUTPUT Control structures are the statements or groups of statements (modules) in a program and algorithm by which the order of processing is controlled. Using them properly is the most important part of programming. BASIC is a line numbered language. The order of processing in a program is from the lowest line number in the program sequentially through to the highest, unless this is changed by using a control structure. Control structures link the different modules in a program together and are themselves modules. They will be dealt with in depth in the remainder of this section. To make our algorithm language-independent we can write them using a standard notation in pseudocode for the particular control structure together with its flowchart description. When we code the structures into the BASIC language the instructions used and the order of statements in the structure may be slightly different according to the version of BASIC and how ‘structured’ it is (i.e. how easily it accommodates these control structures). The structures we will study in BASIC are: (i) DECISION STRUCTURES (ii) TRANSFER STRUCTURES (iii) LOOPS (iv) SUBROUTINES (v) NESTED STRUCTURES (vi) SUB-PROGRAMS 67 DECISION STRUCTURES Computers make decisions by comparing the value of one variable against another. For example: IF А-0 THEN (do something) IF AS = “YES” THEN (do something) To make decisions they use relational (or conditional) and logical operators, like the equals operator above. Sinclair BASIC uses three decision structures: Simple decision Double decision Multiple decision As a result of these decisions control may be transferred to another program module, or local processing within the structure may take place. TRANSFER STRUCTURES These structures involve: (i) UNCONDITIONAL TRANSFER which is a direct transfer of control using a GOTO (line number) statement. Transfer is to another program statement or a module consisting of a group of statements. GOTO is a very powerful structure and must be used with care. (п) CONDITIONAL TRANSFER in which transfer of control to another segment is made as the result of a decision: i.e. IF (condition is true) THEN GOTO (line number). These program structures are discussed further in Section H. LOOPS The need for the repetition of simple tasks is one of the fundamental reasons computers exist. Loop structures are incorporated in most computer programs. A loop is a sequence of repeated steps in a program. This repetition must be controlled. We shall see in Section L that repetition is controlled by: (i) COUNTING (ii) TESTING FOR A CONDITION 68 There are three common loop structures: (i) Repeat (the process) forever! (ii) Repeat (the process) until (a condition is met). (ui) While (a condition holds) repeat (the process). Structure (i) is of little use, except that we have to note it and make sure it does not occur. In structure (11) the condition is tested after processing. In structure (iii) the condition is tested before processing. Sinclair BASIC uses a convenient and powerful set of statements for controlling repetition by counting called: FOR - NEXT Statements SUBROUTINES Structured programming involves breaking down а complicated problem into subproblems which can be worked on separately. SUBROUTINES are such separate independent program modules. They are distinct from SUBPROGRAMS which have similar properties in that they are routines or groups of program statements that are repeated more then once during a program run. Subroutine modules have a unique address and can have a name (like a person who lives in a house). Transfer of control to the subroutine from the MAIN PROGRAM, when the program runs is by reference to the subroutine address through a special SUBROUTINE CALL INSTRUCTION. This is the GOSUB (address of subroutine) statement. A return of control to the main program to carry on processing from where it left off is through a special instruction: RETURN. Subroutine structures in Sinclair BASIC are explained in Section N. NESTED STRUCTURES These are program modules or structures that lie entirely embedded within each other (like a set of Russian dolls). A simple nested structure 1s MODULE 1 MODULE 2 MODULE 3 69 In terms of program statements this would look like: module 1 Inn 222 s, 20 module 2 40 . — BE ыз шч module 3 SEL CIIM 2 80 IUD Ш. 120. — ——— ГІП... 140. 1. The flow of control is: START MODULE 1 TRANSFER CONTROL ——— 9» START MODULE 2 TO MODULE 2 TRANSFER CONTROL —————» START MODULE 3 TO MODULE 3 ү? COMPLETE MODULE 3 TRANSFER CONTROL BACK TO MODULE 2 COMPLETE MODULE 2 TRANSFER CONTROL BACK Subroutines, subprograms, loops and decisions may be nested in programs. Nesting is dealt with more fully in Sections H, L and N. G6: The Data Table When designing a program it is important that our knowledge of the data and information pertaining to the problem is complete. All data will need to be assigned a VARIABLE name, unless it is a numeric constant used in a formula. 70 The variable type will be either: NUMERIC - numbers - A, N1, COUNT, A(I,J) STRING -characters - A$, AS(I,]J) LOGICAL - numbers or characters - A, A$, NOT B Numeric variables will be integers, fractions, real and imaginary numbers. Strings will be names, characters and symbols. Logical variables will be the values TRUE or FALSE, 1 or 0 as appropriate to their use. Logic is dealt with in Section R. We also require to know whether our data is: INPUT OUTPUT or INTERMEDIATE Intermediate data is used in the body of the program, e.g. the value of a loop counter, or the intermediate result of a calculation. Intermediate data is useful for testing and debugging purposes when running the program or algorithm, using machine or hand traces. The equations, functions and expressions that will use the variables will need to be known. When dealing with equations, functions and expressions the units of the variables or parameters concerned must be known and should be stated. The first and simplest data table to construct is a descriptive list of variables to be used in the program. This is important for documentation purposes. For example: VARIABLE DESCRIPTION ITPR A First number Input B Second number Input SUM Sum of A and B Output A$ User response to Input ‘RUN AGAIN?’ For program design purposes the value ascribed to each variable at different points through the programs can be added. This forms a data table that is useful for checking the algorithm before and after coding it into BASIC, and is also a way of analysing errors in your own program, and understanding how other programs work. 71 ALGORITHM VARIABLES MODULE N N. 1 Loop counters are included in the list of variables. If their values are used for calculation inside the loop, this should be stated. There are some examples of this type of data table in the text. REFINING THE ALGORITHM The tree diagram should be further broken down and refined until the final sub-modules correspond to recognisable BASIC statements and structures. As you get more experienced, you will recognise more complex structures, and the solution to a problem wil become apparent at an earlier stage. G7: Describe the Algorithm 1.4.1 WRITE OUT YOUR METHOD OF SOLVING THE PROBLEM (THE ALGORITHM) IN STEPS ІМ А SIMPLE ENGLISH STYLE (PSEUDOCODE). 1.4.2 DRAW A FLOWCHART SHOWING HOW THE PROGRAM WILL RUN FROM START TO FINISH. 1.4.3 TEST THAT THE ALGORITHM WILL WORK BEFORE CODING IT INTO BASIC. Having broken our problem down into distinct things to do, or subproblems, to a stage where we are able to write a BASIC program, we need to do at least two things before we code. These enable us to write programs that work and that other users can understand. The algorithm description in pseudocode or flowchart form is an important point of the documentation of your programs. This is not written as part of the program but as a separate document which will also include a listing of the program. This is important for other programmers who may want to modify your program or use it as part of a larger program, and for you yourself if you come back to it after a 72 period of time and cannot remember how you designed it! The program listing alone is often not enough, if the algorithm is complex, to show how the program works. G8: The Pseudocode Description In the structure or tree diagram - which we draw out in rough on a piece of paper as we design our solution — each block or module right down to the lowest level has an English description of the task to be done inside it. (The very lowest level tasks will be described in sentences that are very similar to the BASIC program statements themselves, as you will see in Programming Methods II.) Our algorithm will be written out, in a step-by-step fashion, and will include all the descriptions in the boxes. The highest or first level description (simple box) will be the algorithm and program title. The second level will be the titles of the program sections. Each of these major sections will encompass a further group of modules, all of which will be named in our description of the solution. The lowest level of our tree diagram will be the specific instuctions the computer has to perform. These will be translated into the BASIC language on an almost one to one basis, and will contain the important and easily recognised language structures, for making decisions, branching and jumping, and repetition that we have previously mentioned. (A summary of pseudocode descriptions of some control structures and their flowcharts with BASIC program equivalents is given in Section 0, Programming Methods II.) If you imagine turning the tree diagram on its side and taking away the boxes, the descriptions that are left constitute a pseudocode description of the algorithm. As an example, let’s look at the tree diagram and the algorithm description for the problem of asking our robot to make a pot of tea. Using our tree diagram we can write down our algorithm for making a pot of tea as a sequence of instructions (to be coded later into a computer language). We use the English language as our pseudocode and our program is written directly from the sub-tasks in the bottom line of boxes in the tree diagram. We use the boxes at higher levels in the tree to define distinct modules. Comments or REMARK statements identify each module and explain what is being done in each algorithm section: Remark * * Algorithm for robot to make pot of tea * * Remark * Boil water - task 1.1* 1,4,4 ЕШ the Кеше with water 1,1-4 Walt until the water is boiling 1.3 Plug in the kettle and turn it on Remark * End of task 1.1* Remark* Module - Put tea in the pot — task 1.2 * Ix Get toe pot 1.2.2 Put 200 tea bags in the pot 73 Remark” Епа of task 1,2% Remark * Module - Put water in the pot - task 1.3 * 1,2,1 Take pot to kettle 1,2,2 Stir tea with spoon 1.54 Put lid on tea pot Remark * End of task 1.3 * Remark * * End of Algorithm - tea is made * * You can see that the tree diagram shows why each part of your algorithm is included and why it is in the particular position in which you have placed it on the tree. The tree diagram contains information about three things: (1) The problem broken down into different levels of detail starting from the general concept of what is to be done down to the specific activities and instructions which will enable the problem to be coded. (2) ‘The order in which instructions must be performed. (3) The comments which must be included to explain what the program is doing. Exercises 1 Our algorithm has the following mistakes in it: a) Some instructions are wrong. They are spelt incorrectly and the robot will not be able to recognise them. b) Some instructions are in the wrong order. c) Some instructions are missing in the algorithm. d) Some instructions are missing on the tree diagram. Find the mistakes! 2 Correct the tree diagram and the algorithm. 3 Expand the tree diagram and the algorithm to a further sub-task level. For example: „л Fill the kettle becomes 1.1.1.1 Put kettle under tap 1.1.1.2 ‘Turn on tap etc. 4 Draw а tree diagram and write the algorithm in pseudocode for a robot to set up and switch on your microcomputer system. G9: Flowcharts Flowcharts are a second graphical method used in designing programs. They consist of linked boxes of different shapes. Each shape has a different use and, as with tree diagrams, each contains a brief description of what the program should do at a particular point. It is harder to design programs using flowcharts than with tree 74 diagrams. Their power comes from using them to help make visible and describe the flow of control in the algorithm and the resulting program. They are used to help code the program into BASIC instructions, and later form an important part of the DOCUMENTATION оға program. Note that flowcharts express the important control structures used in programming in diagram form. We give a selection of standard flowchart symbols here. There are additional ones, but their usage varies. The conventions of use should be followed if you wish other people to understand your flowcharts. For your own use, in analysing programs, you may be less exact, but not less systematic. Flow in a program can be illustrated by a selection of blobs and rectangles only, given that the lines of flow are correctly given, and the right words are written in the blobs! Doing this is all right for yourself, but not if your flowcharts are to be comprehensible to others. FLOWCHART SYMBOLS Flow lines. These connect the program blocks. Y “pes The arrows show the direction of flow, and are very important. This symbol represents any kind of processing function, that is general Programming dinis Statements, i.e. ''Purchase Tea'' or LET A- В + С. This represents а decision, with а Conditional — test, e.g. “Is there another shop open” or <> IF A=3 THEN ... It has a Yes/No branch, No according to whether the condition is True or False, which determines the program flow. This represents either Output in the program m" to the screen or printer, or Input from the keyboard, e.g. PRINT “HAVE YOU A PACKET OF TEA?” or INPUT B. This represents a named process that is specified elsewhere, e.g. Subroutine GOSUB 1000. The subroutine would have a separate flowchart. 75 This represents an exit to or entry from another part of the flowchart, allowing one part of the chart to be connected to another part. Used when another direct line link would be confusing, or to connect to a separate page. This represents the Crossing of two Flow Lines. They are not connected. This represents the Junction of Flow Lines. The two lines of flow join. STOP Terminal Point, e.g. Start, Stop, Pause. A flowchart does not branch out like a tree diagram. It always converges to the stop point. It has a direct relationship to the program it describes. Writing down a flowchart is rather like drawing a diagram of the program itself. Below are some examples of simple flow structures, with the program and the flowchart. FLOWCHART PROGRAM 1. Simple sequences 10 LET X = 5 20 INPUT Y 30 PRINT X,Y FLOWCHART PROGRAM 2. Decision and program branch 40 IF Y-0 THEN GOTO 70 50 LET X=100 60 GOTO 80 70 LET Х-0 80 PRINT X 90 STOP Notice that we have omitted a flowchart symbol for line 60. This GOTO is indicated by the flow lines. The same is true of the GOTO in the conditional statement of line 40. 10 INPUT X 20 IF X-0 THEN GOTO 50 30 PRINT X 40 GOTO 10 50 REM **END** PRINT X 77 : Notice that the above flowcharts represent the programs line by line. Flowcharts can also be less detailed, and the flowchart symbols used to represent program blocks (sequences of program instructions) or modules rather than one or two lines. They then describe a less detailed flow structure. We might have a flow that was represented like this: INSTRUCTIONS INPUT 10 NUMBERS FIND SUM, AVERAGE This is like a flowchart of a higher (less specific) level of a tree diagram. Each section could have a more detailed flowchart drawn up to show the individual lines of the program, or comments could be added to the blocks above, relating the program lines to the blocks: 78 INPUT Input loop in lines 10 а Г 40 t NUMBERS o 69 You will soon start to write short programs, and should draw up flowcharts with each program line or instruction indicated separately. Later, for longer programs with large numbers of lines, the flowcharts must be condensed where the sequence is simple to follow in the program, to keep them of manageable size. Any complex manipulations should still be included in full. EXAMPLES (1) Here is a flowchart for our robot. We are going to ask it to buy a packet of tea. ENTER SHOP HAVE YOU A PACKET OF TEA LS THERE ANOTHER SHOP PURCHASE TEA 79 In the same way as our ‘making a pot of tea’ problem which the robot has to solve, each of these boxes must be broken down into simpler instructions. On a simple flowchart it may not be possible to see how the problem has been broken down. What we must do is either draw the whole flowchart again with more detail or draw new expanded flowcharts at specific points, e.g. “ENTER SHOP” could be replaced with the following: 80 (2 Here is a flowchart of a program to input two numbers, output the sum, and ask you if you want to run the program again. 81 INPUT À INPUT B LETS = A+B PRINT S PRINT ‘‘RUN AGAIN? (ҮЕ5/МО)” INPUT A$ IF A$ = ‘‘YES’’ THEN GOTO 10 STOP AN EXAMPLE OF STRUCTURED DESIGN Problem: Find the average of five numbers: (1) TREE DIAGRAM Find Average of 5 numbers Get each Set counter number, add Find Print & sum to Q it to the sum Average Average Let Sum = Let Counter Add 1 Input to counter number End of summing if counter = 5 Let Let If Counter Let Print Counter = Sum = = 5 then Average Average Counter +łŁ Sum+X end summing =Sum/5 (2) FLOWCHART START SET COUNTER -0 92 ADD COUNTER Note that the flowchart and program test whether the counter value is less than 5, using the < symbol. (3) PROGRAM REM “AVERAGE” REM ** PROGRAM FINDS AVERAGE OF FIVE NUMBERS INPUT ** REM ** START ** LET SUM = 0 LET COUNTER = @ LET COUNTER = COUNTER + 1 INPUT X LET SUM = SUM + X IF COUNTER < 5 THEN GOTO 60 83 100 LET AVERAGE = SUM/5 110 PRINT AVERAGE 120 KEM ** END ** The operand “” means ‘divided by’ and is equivalent to the ‘+’ symbol. Exercises 1 Design an algorithm (using tree diagram) and write a BASIC program with a flowchart to find the sum and average of ten numbers to be input at the keyboard. 2 Produce the tree diagram, flowchart and program which calculates the area of any rectangle. 3 Design the algorithm, BASIC program and flowchart which calculates the total volume and weight of three boxes to be airfreighted from London to New York. Use the following data: BOX LENGTHCM BREADTHCM HEIGHTCM WEIGHT KG 1 20 4 2 2 2 40 3 6 2.5 3 70 10 15 20 Test that it works! G10: Testing the Algorithm It is always best to make sure your method of solving the problem actually works before coding it into BASIC. This pre-coding check is known in the programming trade as a DRY RUN or WALK THROUGH. Using the DATA TABLE, we check through, module by module, the values of all the variables, expressions and counters step by step through the algorithm. This will uncover errors in the logic and method and will save time when debugging the finished product later on. Professional programmers always do this as they have to work to very tight time schedules, and by doing things properly at the start they save time later on. We would like you to try a few walk throughs on the simple programs you will be designing at first, just to get the hang of the idea. We have now covered the first essential steps in designing a program and have seen a simple coding process. We have talked about methods and concepts and introduced some new terminology. After concepts we go to detail. The algorithm is ready to be coded into a BASIC program. In doing this we are going to put into the program the fundamental programming tools, which are language structure and control structures. We have to know what these structures or tools are before we can use them. This requires a look at how Sinclair BASIC, through small groups of instructions, enables decisions to be taken, branching 94 and jumping to different parts of the program to happen, repetition of parts of the program to take place and how separate modules called subroutines and sub-programs can be called into action where necessary — these are the language structures. Let’s go and meet them! 85 SECTION H: CONTROL H1: Control in Programs The statements which make up a BASIC program are numbered. BASIC is thus called a LINE NUMBERED LANGUAGE. Control in all BASIC programs is carried out by reference to these line or statement numbers. The ZX81 and Spectrum will normally run a program from the lowest numbered statement through to that with the highest number unless instructed to do otherwise. This is exactly what concerns us here, and thus we need to recognise that we can control the order in which program statements are executed by using four important instructions in Sinclair BASIC: - GOTO (for direct transfer) - IF-T HEN (for decisions and branching) - FOR-NEXT (for loops (repetitions)) - GOSUB-RETURN (for accessing program modules called subroutines) These instructions are used singly or combined together with other instructions to form groups of program statements called CONTROL STRUCTURES. There are four principal control structures: - DECISION AND BRANCH - LOOPS - SUBROUTINES - NESTED STRUCTURES In this Section we will discover how to take decisions and branch to other parts of the program. We will study the remaining structures later in Part Three. The most important property of a computer is that it can be programmed to make decisions, by using the relational or conditional operators of BASIC. H2: Condition Testing CONDITIONAL OPERATORS Conditional operators are also called relational operators as they determine the logical relationship between two expressions, numeric or string, as: Equality: = Inequality: «<> Greater than: > Less than: < Greater than or equal to: >= Less than or equal to: < The priority of conditional operators is 5. Priority will be explained in Section J. They are executed in order left to right across a statement unless in brackets. We often need to use the complements or opposites of these operators in decision making. The complements are: Operator Complement equality = inequality <> greater than > less than or equal to < = greater than or equal to > = less than < The reverse operations are true in each case. H3: IF-THEN IF-THEN Conditional operators are used with: IF-THEN statements IF (CONDITION IS TRUE) THEN (PERFORM AN INSTRUCTION). For example: 40 IF (А = B) THEN GOTO 10 50 IF C <=6 THEN STOP 60 IF J > K THEN PRINT “J” The format of the statement is: IF (CONDITION) THEN (INSTRUCTION) Any BASIC instructions can be used in this kind of statement, although a number are unlikely to be useful (e.g. NEW, CLEAR). In general if the condition in the program line is TRUE then the instruction following the condition is obeyed. If the condition is not TRUE (FALSE) then control passes to the next line. This powerful facility enables us to branch and transfer control to another line in the program. IS YES BRANCH THE CONDITION (TRUE PATH) TRUE? NO BRANCH (FALSE PATH) GO TO THE NEXT LINE 87 H4: GOTO [Instructions GOTO The normal control sequence in a program is via numbered statements — from the lowest to the highest. GOTO (line number) switches control to the line number specified: 100 GOTO 20 200 GOTO (B + C) As a command GOTO 30 executes a program from line 30. Unlike RUN, with this method variables are not cleared before execution. The Spectrum includes a space between GO and TO when printing this instruction. Exercises Key in and run this program which checks that only positive numbers are input and gives a bad data error message as well as prompting for the next input. Notice the use of IF-THEN and GOTO. INPUT both positive and negative numbers. 10 REM*INPUT CHECK* 20 INPUT A 30 IF A»0 THEN PRINT A 40 IF A«-0 THEN PRINT "BAD IN PUT" 50 PRINT "HAVE YOU ANOTHER NUMB ER? ANSWER YES OR NO" 60 INPUT AŠ 70 IF А5 ="YES"THEN GOTO 20 88 STOP 90 REM*END INPUT CHECK* Now try these exercises which demonstrate the power of GOTO: 1 10 PRINT “CENTURY”; 20 GOTO 10 Run this program 2 10 GOTO 80 20 PRINT “COMPUTERS'”'; 30 GOTO 10 40 PRINT ‘‘PERSONAL”’; 50 GOTO 20 88 60 PRINT ''SINCLAIR''; 70 GOTO 40 80 GOTO 60 Key it in and sort it out! This is called ‘spaghetti programming’. Structured programming techniques have been designed to avoid the excessive use of GOTO statements. 3 10 INPUT A$ 20 PRINT A$; 30 GOTO 10 INPUT some graphics characters and watch the patterns! 4 Кеуіп and run this example: 10 INPUT A 20 IFA = 1 THEN FORI = 1 TO 10 30 PRINT “CENTURY” 40 IF A=1 THEN NEXT I 50 STOP Line 10 asks you to input a number. Line 20 examines if it is equal to 1. IF this condition is TRUE then a FOR-NEXT loop is set up to print “CENTURY” ten times. If it is not TRUE then control passes to the next line. Line 30 “СЕМТГКҮ” is printed once. Line 40 the condition is tested again. If TRUE the loop continues and CENTURY is printed again. If not then control passes to line 50. Line 50 stops program execution. Can you understand it? If not wait until you have read the section on LOOPS. H5: Decision Structures DOUBLE DECISIONS The simplest decision involves the evaluation of a LOGICAL CONDITION - i.e. a condition that may have the value of either TRUE or FALSE. A result of this evaluation decides which part of a program is executed next. These parts of the program are called TRUE TASK and FALSE TASK. 89 The flowchart for the Double Decision STRUCTURE is: It is called a double decision as there are two alternative modules that can be performed. In the flowchart, if the indicated condition 1s true, then the program section representing the True task is carried out, otherwise the program section representing the False task is performed. Only one of the paths from the condition test is taken, and the program will continue at the statement represented by the arrow at the bottom of the flowchart. Each task can be a single instruction or a statement or a group of instructions. The Double Decision Structure is known by the general name of the "IF-THEN-ELSE Decision Structure’’. Its general form 1s: IF (condition) THEN (true) ELSE (false) This means: IF the condition tested is True THEN perform the True task, and IF the condition is not true perform the False task. Our algorithm description of it would look like: 1. Decision Module. 1.1 Do the test. If result is True then 1.22 По True task 1.3 Otherwise do False task We can write this formally in pseudocode as: 90 module - decision if condition then True Task else False Task end if end module End if and end module are bounds to the structure. In Sinclair BASIC we code it as: 10 IF (cond) THEN (branch to True task) 20 (False task) Note that in this case the only literal equivalent of BASIC from the pseudocode is with the use of IF and THEN. The branch to the true task is made with a GOTO instruction. For example: 10 IF A»0 THEN GOTO 100 20 REM * FALSE TASK * ЗӨ uus 90 GOTO 120 100 REM * TRUE TASK * 110 PRINT A If we did not branch to the true task starting at 100 and used: 10 IF A20 THEN PRINT A 20 REM FALSE TASK in line 10, the true task would be processed and control would then pass to line 20 - the false task. In other words, both tasks would be processed! Watch out for this. EXAMPLE: Input two names as strings. The program compares them and prints them out in alphabetical order: 91 14 REM * ALPHA * 20 INPUT A$ 30 INPUT B$ 40 IF A$10 THEN STOP 30 GOTO 10 5ТОР Note the abbreviation of True to Т апа False to F. MULTIPLE DECISIONS There is often the need in programs to perform several tasks based on the result of a set of conditions. To solve these problems we use a 93 multiple decision structure. This kind of structure is especially useful in breaking up larger tasks into smaller ones. Multiple decisions are most conveniently handled by multiple logical operations. This is covered in Section R. We will consider the conventional way of handling them. As an example of multiple decisions consider a food vending machine. You put a coin in and press the respective button of the article you wish to be delivered to you. Another example would be a set of arithmetic testing programs, with questions in each. The computer would ask you which set of tests you required, you would key in the reply and, from several alternatives, the required program would run. The flowchart for such a structure is: START Where C1, C2, C3 are the conditions and Р1, Р2, P3 are the True tasks. EXAMPLE: Input any of three letters A, B, C and print out a corresponding reply. = FRINT "ENTER AoE üR C" 10 INFUT ñ$ 20 IF АФ-"А" THEN GOTO 60 94 30 IF А%Ф-"Е" THEN GOTO ЕО 40 IF AS="C" THEN GOTO 100 20 STOP 60 PRINT “YOU INFUT A" 70 STOP S0 FRINT “YOU INPUT Е" 90 STOP 100 PRINT “YOU INPUT C" 110 STOF The Pseudocode description of this structure is: case if Cl then P1 10 IF (C1) THEN (P1) if C2 then P2 20 IF (C2) THEN (P2) if C3 then P3 30 IF (C3) THEN (P3) endcase endmod PROGRAMMING WITH GOTO When programming in BASIC take great care in how you use the GOTO statement. It takes two main forms. Used on its own it 1s called an unconditional GOTO and when used with IF-T'HEN it is called a conditional GOTO. GOTO enables you to jump around in a program like a flea on a blanket - don't do it! Try and code your program to execute in sequence and avoid it becoming a bowl of spaghetti. Excessive use of GOTO makes programs difficult to refine and debug. Relationships between the program paths become difficult to follow. However — do not take the other extreme and write awkward complicated code to try and avoid GOTOSs! Ideally, unconditional GOTO statements should only be used to skip over code and not to repeat code sections (i.e. they should only be used to transfer control forward in a program). Do not put an unconditional GOTO inside a loop or subroutine to jump out of it. Do not jump inside a loop or subroutine, because you'll find that jumping in and out of loops can cause unpredictable results. Do not jump to another GOTO. For example: 100 GOTO 200 200 GOTO 300 95 or else 100 GOTO 100 ! Exercises 1 2 H6: L Write a program to input integer numbers and stop if zero is input. Write a program to input integers and count the number of times zero 15 input. Write a program to input integers and calculate the percentage of zeros input. Write a program which prints out the result of dividing any two numbers’ input and gives a “Һай data - try again” message if any of the input values is zero. Write a program which will print out on request a lunch menu for the different days of the week. ogical Operators: AND/OR We will only introduce you to simple logical operations here. Logic is dealt with fully in Section R. Use of the AND and OR statements enables us to combine conditional statements in powerful ways to make more complex decisio ns in programs. AND AND combines relations so that the expression: e.g. (condition 1) AND (condition 2) (A = B) AND (В>1) is TRUE when BOTH conditions are TRUE. It is FALSE when one or both conditions are FALSE. OR e.g. OR combines relations so that the expression: (condition 1) OR (condition 2) (A = B) OR (B<>1) is TRUE when EITHER condition is TRUE. It is FALSE when both conditions are FALSE. The expressions formed by the use of AND and OR are used with LE ua d. HEN statements. For example: 20 IF Х>1 AND X«10 THEN PRINT '* BETWEEN 1 AND 10” 96 50 IFX<>2 AND X<>3 THEN PRINT < A МОТ EQUAL TO 2 ОҚ” 40 IF A=B OR B=C THEN LET F=F+1 The first example will be true if X is greater than 1 and X is also less than 10, and the message will be printed. If X was 11, the first condition would be true, but the second false. The whole expression would then be false. Notice the danger with the second example, in that we say in English ‘not equal to 2 or 3’, but we must key in an expression using AND. It is clear once you realise that two conditions are to be tested — ‘not equal to 2 and not equal to 3’. If, for example, X were 3 when this line in the program was reached, then the second condition would be false in this expression, and the whole expression would also be false. The third example would be true if ezther A was equal to B or if B was equal to C. It is also true if both these conditions are true. We can also combine more than two conditions: 20 IF A=BANDB=CANDC = 20 THEN STOP will stop if all three conditions are true. If one or more is false then the whole expression is false. Similarly: 20IFB-20R B-3ORB-4THEN LET B- 1 will make B - 1 if B is equal to 2 or 3 or 4. It is also possible to use combinations of AND and OR: 30 IF (A = BAND B>2) ОК (A = 2 AND B = 3) THEN GOTO 60 The expressions in brackets are evaluated first. The first expression in brackets will be true if B is greater than 2 and equal to A. The second expression will be true if A is 2 and B is 3. The program will pass control to line 60 if either expression in brackets is true. To summarise: where T1, T2 etc. are true conditional expressions and F1, F2 etc. are false conditional expressions: (T1) AND (T2) TRUE (T1) AND (F2) FALSE (F1) AND (T2) FALSE (F1) AND (F2) FALSE (T1) OR (T2) TRUE (F1) OR (T2) TRUE (T1) OR (F2) TRUE (F1) OR (F2) FALSE Each condition may also be another AND or OR expression. Exercises Work out what will be printed by these programs, then key in and run them to check. The operator ‘‘/’’ means ‘‘divided Бу” (+) and “%” means ''multiplied Бу” (*). 97 Make sure you have got the programs correct before you run them. Work out both sides of each expression using a relational Then, giving each expression a T or F value, work out the bracketed AND/OR expressions. This gives you a T or F value for the whole bracket. Then work out whether the whole operator first. LET A=2 LET B=3 LET С-10 LET X=15 IF X/B=A AND C/A=5 THEN PRINT "LINE 50 TRUE" IF X/B-A OR C/A=5 THEN PRINT "LINE 60 TRUE" IF X/B=C/2 AND X>=15 THEN PRINT "LINE 70 TRUE" LET A-20 LET В-150 LET X=7.5 LET Y-2 LET 5-В/20 IF S=X AND X*A-B AND Y-2 THEN PRINT "LINE 60 TRUE" IF X-B OR X«20 OR X>2 THEN PRINT "LINE 70 TRUE" IF (X=7.5 OR Ү-10) AND (A/Y-1 @ AND В-150) THEN PRINT "LINE 80 TRUE" expression will be true or false. Write some similar programs for yourself to experiment with all the relational operators used with AND and OR. 98 SECTION I: PRINTING I1: PRINT LPRINT PRINT The PRINT statement is used to output information by displaying it on the screen. It can take many forms. For example: 10 PRINT A prints out the value of numeric variable A 20 PRINT B$ prints out string variable B$ 30 PRINT “YOUR NAME?" prints out whatever is included within the quotes (inverted commas) 40 PRINT (B**2 — 4*A*C) prints out the calculated value of the expression 50 PRINT leaves a blank line LPRINT The LPRINT statement is used to output information by printing it out on the printer. The LPRINT statement is used in exactly the same way as the PRINT statement, but produces printer and not screen output. If the printer is not attached LPRINT statements are ignored. The screen size for printing is 22 PRINT lines down the screen, and each line is 32 columns (character spaces) wide. The actual screen size is 24 lines by 32 columns, but the bottom two lines are reserved for commands and operating messages. The lines are numbered @ to 21 down the screen and the columns 0 to 31 across. The PRINT statements shown above each commence at the left-hand side of the screen, and each PRINT statement moves the printing position to the start of the next line after it prints whatever it was told to. Lines of greater than 32 characters will go on to the next line automatically. To clear the screen of printing we use the CLS (Clear Screen) statement. 99 CLS CLS erases all printing on the screen, and sets the new print position at the start of the top line of the screen. I2: Spacing Items on the Screen Е А semicolon (;) between two items causes the printing of the second item immediately after the first. For example: 10 PRINT A;B$ 20 PRINT “АУЕКАСЕ”;С Try the following program: 10 LET A=6.89 20 LET B=87.6 30 PRINT A;B 40 PRINT ''AVERAGE"'';(A + B)/2 The display is: 6.8987.6 АУЕКАСЕ47.245 This does not give а very satisfactory display since values run into each other. One simple way to overcome this is shown below. 10 LET A= 6.89 20 LET B=87.6 30 PRINT A;" "В 40 PRINT “AVERAGE ”;(А+В)/2 The display now becomes: 6.89 87.6 AVERAGE 47.245 ci A comma (,) between two items causes the print position to be shifted on (at least one place) to either column 16 or to the next line column 0. For example: 10 PRINT A,B 20 PRINT A$,B$ 30 PRINT “АУЕКАСЕ”,С Try the following program: 10 LET A= 7.65 20 LET B= 8.67 30 PRINT “AVERAGE” (А + B)/2 100 40 PRINT 50 PRINT ‘‘NUMBER!1’’,‘‘NUMBER2’’, “АУЕКАСЕ” 60 PRINT A,B,(A + B)/2 The display is: AVERAGE 8.16 МІ/МВЕК1 NUMBER2 AVERAGE 7.65 8.67 8.16 Clearly the comma is useful if we wish to print a table with two columns, but is unsuitable if we wish to have a table with more than two columns. It is important to remember the screen size when deciding the form of your output. For your output the effective screen is 22 lines each 32 columns wide. TAB TAB C; moves the print position to column C. If this would involve back-spacing it moves on to the next line. The following program (with printout) indicates how the TAB function can be used to improve the presentation of results. 10 LET А$ = “А.В.ЈОМЕЅ” 20 LET B= 65 30 PRINT “NAME”;TAB 6;A$; TAB 19:“АСЕ”: TAB 23;B;TAB 27; “YEARS” NAME A.B.JONES AGE 65 YEARS Note the semi-colons between TABs and print items. It is important to remember that each line has 32 columns, numbered 0 to 31. The next program shows a simple way of tabulating results. 10 PRINT “МО.”;ТАВ 4;“5ОСАКЕ”;ТАВ 12; “СІУВЕ”;ТАВ 20;*RECIP" 20 INPUT N 30 PRINT N;TAB 4;N*N;TAB 12;N*N*N; TAB 20;1/N 40 GOTO 20 101 NO. SOUARE CUBE RECIP 1 1 1 1 2 4 8 0.5 3 9 9/ 033333333 4 16 64 0.25 5 25 125 0.2 6 36 216 @.16666667 7 49 242 0.14285714 8 64 512 0.125 9 81 729 0.11111111 10 100 1000 0.1 It is important to remember that numbers are output with up to 8 figures and allow the appropriate space. An alternative is to decide how many figures you want and use the INT function (see Section J). I3: PRINT AT AT L, C moves the print position to line L and column C. For example: 10 PRINT AT 10,12“ CENTRE" will cause the string specified to be printed starting at line 10, column 12, i.e. roughly in the centre of the screen - since L goes from 0 to 21, counting down the screen, and C goes from 0 to 31, counting left to right. EXAMPLE The program below sets up a symmetrical pattern using the character of your choice. Note the use of the command CLS to clear the screen of your input. 10 PRINT AT 5,4;"WHICH CHARACTER?" 20 INPUT AŠ 30 CLS 40 LET L=INT (RND*10)+1 50 LET C=INT (RND*15)+1 60 PRINT AT 11%,,164С;А65 70 PRINT АТ 11-L,16-C;A$ 80 PRINT AT 114L,16-C;A$ 90 PRINT AT 11-L,16+C;A$ 100 GOTO 20 Try adjusting the parameters in lines 60-100. The important feature to remember is: Number of character cells is 32 horizontally by 22 vertically, i.e. 32 x 22 altogether. The TAB function uses C = @ to 31 only. The AT function uses L = 0 to 21 and C = 0 to 31. You should have noticed that the PRINT commands reinforce each other, and provide alternative ways of achieving the aim of placing characters, character strings or numbers at the desired positions on the 22 line, 32 column screen display. For example, these three programs: 19 LET X = 3 20 PRINT X,,;, 30 PRINT X*X 10 LET X = 3 20 PRINT X 30 PRINT 40 PRINT X*X 10 LET X= 3 20 PRINT X,TAB 32;" "TAB 32;X*X would give the same printout on screen. The number of keystrokes (count them) is what determines which statement usage is efficient in any instance. You will soon come to recognise which to use if you experiment. PRINT AT instructions will overprint anything already printed at the position specified. We can use this to replace on the screen one set of data, or one string, by another. 10 INPUT X 20 PRINT AT 0,0;X 30 GOTO 10 overprints one X by the next X each time. If we input 1,2,3...10 it works fine. But if we input 10,9,8...1 we get: etc. Similarly, ZU ЕТТІ” 40 PRINT AT 10, 10; “SINCLAIR” works, but not if we swap the two strings around - we end up with ZX81LAIR, and we have the same problem with numbers, which can be between one and eight digits long. We can blank out something on the screen by overprinting an empty string. For the simple problems above, the addition of appropriate 103 strings will work; we add 4 spaces after “27Х81”, so that line 10 becomes: 10 PRINT AT 10,10; “ZX81 E and for numbers, we can use: 20 PRINT AT 0,0;X; *“ id (7 spaces) Using LPRINT also requires care. For the LPRINT instruction, TAB works exactly as PRINT TAB. LPRINT AT L,C is converted to LPRINT TAB C, and the line number is ignored. This is because the printer cannot go back to a previous line. Try this program. Input 1,2,3,4,5. 10 INPUT X 20 LPRINT AT X,X;X 30 GOTO 10 will print 12345, as if line 20 had read LPRINT TAB X;X. For any programmed screen format that 1s not a simple sequence of print lines, it is better to use COPY to produce output on the printer, once all the data is on the screen. COPY prints the entire current screen display on the printer. If used as direct command, we can COPY less than a whole screen by pressing BREAK before completion, but if used in a program, the whole screen will be copied. 14: The Graphics Characters оп the ZX81* The ZX81 character set includes a set of graphics characters, and you were told how to access them in Section B. To recap: Graphics characters are accessed by using |Graphics| to get the cursor. Repeat to return to cursor. Unshifted keys then produce inverse video characters. (e.g. key Q gives |.) Shifted keys produce graphics cells, if shown on the keys: e.g. SHIFT R gives "W .If no graphics cell is shown, result is inverse video form of normal shifted character (e.g. SHIFT U gives В ). The inverse video characters and graphics cells can be used for enhancing displays and drawing bar charts, diagrams and pictures. They are manipulated as strings, by putting quotes round them, e.g. PRINT “ ER or PRINT “ B”. * The Spectrum offers more extensive graphics facilities than the ZX81, and Spectrum owners should refer to Unit W3 for details. The Spectrum has the solid graphics characters of the ZX81, but not the shaded characters, on keys 1 to 8 in graphics mode. Read through this section bearing this in mind. 104 Put your computer in graphics mode and run through the keyboard, noting the unshifted and shifted versions of each key. Note that RUBOUT (DELETE) works with the cursor, but the cursor control keys do not, and that the cursor must be on screen for them to work. By the time you fill one line and move on to the next, you will see that all these graphics characters Join up, with no gaps between the cells. The difference between the grey cells on the A and K keys is that they Join up with the half-shaded graphics cells on the S, D, F and G keys in different ways. Experiment with these. If they join up properly, you cannot see the Join. If they do not, the Join is visible as a chequered pattern. To check the characters across the screen, use the bottom lines of the screen directly. To check the vertical Joins, enter this program: 10 INPUT A$ 20 PRINT A$ 30 GOTO 10 Change the cursor to [G], then input the graphics character. You have to then press NEWLINE (ENTER) twice; the first time to change to [L], the second to input the character. We can use the graphics characters to draw (crude!) pictures, enhance printout on the screen — by printing prompts in inverse video for example —or putting titles inside surrounds, and use them in diagrams or moving graphics. You'll have to wait a few more chapters before we can do anything interesting, but here are a few things to try: Here’s a program to put a border round a word in inverse video. Notice we store the graphics in string variables. This gives us better manipulative power than if we just used literal strings. On the ZX81 the graphics characters in A$ are the shift graphic on the E key, 11 times the one on the 7 key and the one on the R key. If you are using a Spectrum, the relevant keys are ‘4’, ‘3’ and ‘7’. You can work the other lines out for yourself. A s ie zu зә 46 i се e Notice the combined PRINT AT statements in line 60. The production of inverse characters on the Spectrum (white characters on a black background, unless colour is being used) can be done in different ways. You can use CAPS SHIFT and the 4 key to put an INVerse VIDEO control character before a letter or other character, but this will make a// characters thereafter into their inverse forms unless CAPS SHIFT and 3 is used to restore NORMAL VIDEO. The alternative is to use INVERSE as part of a program 105 statement. INVERSE is obtained using SYMBOL SHIFT and the M key in E mode. To get inverse video this must be followed by 1, so that to print HELLO in inverse video we key in: 10 PRINT INVERSE 1; "HELLO"' This will appear normally in the program listing, but in inverse when the instruction is carried out. Now add the following lines, and you will see why the use of string variables, and variables for the line and column numbers, can be useful. 70 LET X=X+1 80 LET Y=Y+1 90 CLS 100 GOTO 60 Run the program, and you see we have a crude moving display. CLS makes the screen ‘flash’ a bit, but we could avoid this by overprinting. Revise the program to erase by overprinting empty strings. We can use the graphics characters for pictures. Try this: 10 PRINT AT 0,9; “аша ` _ 20 PRINT AT 1,8; === = 30 PRINT AT 2,8; “ "EE" (it’s supposed to be а car). Change the program to allow you to input a value for Line and Column numbers, so that you can place the car in different places. Then add a GOTO loop to allow multiple cars on the screen. Exercises 1 Write a program that puts: ADDRESS: on the screen, then prompts for inputs on line 20 (INPUT NAME etc), and prints the responses on the screen. Each prompt should overprint the previous one. Allow four separate lines for the address. Blank out the last prompt, then have the screen copied on the printer. 106 Add a routine to LPRINT name, address and age, without the borders or titles, on the printer after deleting the COPY Instruction. Input names, ages and occupations of three friends and arrange them to be tabulated in a suitable form. Experiment with ways to make the car move across the screen. 107 SECTION J: ARITHMETIC AND FUNCTIONS Ji: Arithmetic Operations A prime function of the computer is to evaluate formulae and expressions similar to those used in standard mathematical calculation. Algebraic EXPRESSIONS are written in BASIC using the following OPERATORS with a set of variables or numbers as the OPERANDS. ARITHMETIC OPERATOR EXAMPLE SYMBOL NAME PRIORITY BASIC MATHS in exponentiation 10 А**3 А? (raising to a power) [^1] (on the Spectrum) А13 A? - negation 9 -А -А и multiplication 8 A*B AxB (a.b) / division 8 A/B A+B e + addition 6 A+B A+B _ subtraction 6 А-В А-В Note that negation operates on one operand ~ a unary operation ( i.e. makes a variable negative, e.g. — A) and that the subtraction operator uses two operands, e.g. А-В, a binary operation. J2: Priority 1 All arithmetic, conditional and logical operations are assigned a priority number from 10 to 1. High priority is 10, low priority is 1. The priority numbers for the arithmetic operators are as shown in the previous Unit. 2 The priority of an operation determines the order in which it is evaluated in a complex statement in which more than one operation is to be performed. High priority operations are performed earlier. 3 Brackets (parentheses) are used in BASIC algebraic expressions. Brackets clarify which expressions constitute separate values to be operated on. Expressions inside brackets are evaluated first before the quantity is used in further computation. With multiple (nested) brackets the evaluation proceeds from the innermost bracketed expression to the outermost. 4 For operations of equal priority in the same statement, evaluation is from Left to Right. Brackets can often be omitted when the sequence of evaluation is 108 understood, but there is no harm in using them to ensure correct evaluation. Expressions may be tested by using PRINT as a direct command, to check that you have them correct. For instance key in PRINT (8*2.6/5)*2/3 and press NEWLINE (ENTER). The result will be printed on the screen. If a sequence of direct assignments of values to variables is keyed in first (using LET A = 4 (NEWLINE/ENTER), LET B = 3 (NEWLINE/ENTER), etc.) then variable expressions may be evaluated. Using this facility you should experiment with a variety of expressions until you feel confident that you have understood the way in which expressions are evaluated, and the way you have to formulate an expression in BASIC to ensure it returns the desired result. EXAMPLES 1 Evaluation ofa+b-c In BASIC: A+B-C Operators have equal priority; (1) Left to Right A+B (2) L-*EK (A+B)-C 2 Evaluation of ab , (axb) +c In BASIC A*B/C * has same priority as / H LR A*B (2) L*R (A*B)/C 3 Evaluation of a.(2) ‚ах (b+c) In BASIC A*(B/C) (1) Brackets first (B/C) (2 Multiplication — A*(B/C) But notice we could write the expression without brackets in BASIC as B/C*A This is evaluated: H LR (B/C) (2) L= Е (B/C)*A which gives the correct result. 4 Evaluation of (b° - 6c)*+5 In ZX81 BASIC notation: (B**2 = GG )**24 5 (1) Inside bracket; exponentiation B**2 (2) Inside bracket; multiplication 6*C (3) Inside bracket; subtraction (B**2) - (6*C) 109 (4) (5) Exponentiation ((B**2) - (6*C))**2 Addition (((B**2) – (6*C))**2) +5 In Spectrum BASIC notation: (B 2 - 6*C )#2+5 (1) (2) (3) (4) (9) Inside bracket; exponentiation Bez Inside bracket; 6*C multiplication Inside bracket; subtraction (В%2)-(6“С) Exponentiation (В t 2). – (6*C))4 2 Addition (((B f 2) – (6*С)) # 2) +5 2 Computer evaluation of a.b- © + (e - f) d g In ZX81 BASIC notation: A*B - C**3/D +(E-F)/G (1) brackets E- (2) exponentiation Er (3) multiplication/ division L — R А“В C'"3/D (Е-ЕУС (4) addition/ subtraction L > R (A*B) - (C**3/D) + (Е – Е)/С In Spectrum BASIC notation: А*В - С \ 3/0 +(E-F)/G (1) brackets Е-Е (2) exponentiation OTs (3) multiplication/ division L > R A'B Ct3/D (E-FyG (4) addition/ subtraction L > R (A*B) - (C ^3/D) + (E - FG Evaluation of —70 +2х ^ x3-3x7 In ZX81 BASIC notation: 40 +2 "4702 "3.8." Priority 10 4#**2 16 Priority 9 - 70 Negation Priority 8 2°. te *23 377 LR 96 1 Priority 6 - 70 + 96 — Д1 Result 5 In Spectrum BASIC -70 +2*442*3-3%*7 Priority 10 412 16 110 Priority 9 - 70 Negation Priority 8 2> 15 "TET L — R 96 21 Priority 6 - 70 + 96 - 21 Result 9 Exercises 1 Write the order in which the following BASIC expression 1s evaluated: — А + ((B**3/C) - (A**2/D))*(E + Е)/С (ZX81) — А + ((B 13/C)- (A ^ 2/D))*(E+ F/G (Spectrum) 2 Write down the BASIC expressions for: (i) (и? + 2аѕ)^ (ii) ut + Тағ жа b + ac)" (111) 2a (iv) (xy Work out the order in which each of the expressions is evaluated. Test your results on the computer. J3: Number À positive or negative decimal number whose magnitude is between an approximate minimum of: t3x10 ? and an approximate maximum of: +2 x 10” Zero is included in this range. The smallest number the computer can handle is 2.9387359 x 10 `” The largest is: 1.7014118 x 10° The computer stores and calculates numbers internally to an accuracy of nine or ten digits, but prints out the results of calculations to eight significant figures only, rounding where necessary. J4: The E Notation The E or EXPONENT or scientific notation is the notation computers use for input and output of numbers having a large 111 number of decimal digits. E should be taken to read: ‘times ten to the power of’. For example: 1.73 E5 is 1.73 times 10 to the power of 5 1.73%10%%5 (1.73*10 ^ 5 in Spectrum notation) = 173000. Similarly: 3.8E-7 is 3.8 times 10 to the power of — 7 = 3.8*10** 7 (3.8*10 41 — 7 in Spectrum notation) = .00000038. The computer will accept any number keyed-in in this form and will print out numbers in this notation when their values are outside a certain range. For large positive and negative numbers the E notation is automatically used by the computer for numbers > = 10? Numbers up to this figure are first rounded to 8 significant figures and trailing zeros are added until 107 is reached. Key in and run this program: 10 LET A = 9.9999993E12 20 PRINT A 30 ІЕТА =А + 1Е5 40 СОТО 20 Change line 20 to read: | 20 LPRINT TAB 10;A to get a listing of the result on the printer. For small positive and negative numbers the E notation is automatically used for numbers: <= 10^? To see this in action, key in and run the program below: 10 LET A-1.000001E — 5 20 PRINT A 30 LETA-A -(1E- 12) 40 GOTO 20 Change line 20 to: 20 LPRINT TAB 10;A if you want a printer listing of the changeover. Exercises 1 Key in and run the following simple program, which illustrates how numbers are printed, the E notation and the largest number which may be obtained. 112 10 LETA=1 20 LET A=A*10 30 PRINT A 40 GOTO 20 With the ZX81 press and when the screen becomes full, and the message 5/30 appears on the bottom of the screen to indicate no more room on the screen. The Spectrum will display the ‘scroll?’ prompt. Notice the change to the E notation. Note that the program finally stops itself on the ZX81 with the error message ‘6/20’, which indicates an arithmetic overflow (error code 6) as a result of line 20, i.e. the number is too large for the computer to handle. The Spectrum's response is more precise; the error code in this instance will read: ‘6 Number too big, 20:1’. Change line 10 of the program to each of the following and run the program each time. a) 10 LET A=1.00000000 b) 10 LET A=1.1111111 c) 10 LET A=1.7 d) 10 LET A=1.7014118 e) 10 LET A =1.71 What conclusion do you draw? To show that negative numbers behave in the same way, change line 1@ to the following and run the program. a) 10 LET A= -1 b 10 LET A= -1.7 c) 10 LET A= -1.7014118 d) 10 LET A= -1.71 To show how small numbers are handled by your computer a similar program divides a number (A) by increasing powers of 10. Key in the program and run it. 10 LET A=1 20 LET A=A/10 30 PRINT A 40 GOTO 20 Note the change of notation. Notice that after 1E – 38 the computer prints zeros indefinitely, i.e. it has reached the smallest number it can register. Change line 10 to а) 10 LETA=3 Ы) 10 ІЕТА = 2.9 апа ге-гип the program each time. Notice that 2.9387359 E — 39 is the smallest number before zero. Write this number out in full. Can you think of any applications for very large and very small numbers? 113 6 Change the values of À in the program to negative values and confirm that small negative numbers behave in the same way. PROGRAMS TO SAVE IN YOUR TAPE LIBRARY The following two programs should be keyed in, run, listed and saved for your tape library. They both do what the previous programs did but in addition give a printed copy of the results. 10 REM "LARGE NUMBERS" 20 REM** PROGRAM MULTIPLIES + AND - NUMBERS INPUT FROM THE KEYBOARD BY POWERS O F 10 ** 30 REM **KEY IN VALUES FOR A O P +-1,,4-1.1111111,4-1..7,. + -1.7014118,%- 1.71.** 40 INPUT A 50 LET N=0 60 PRINT А%(10%%у) 70 LPRINT TAB 10;A*(10**N) 80 LET N=N+1 90 GOTO 60 For the Spectrum, replace ** by in lines 60 and 70. 10 REM "SMALL NUMBERS" 28 REM**PROGRAM SHOWS PRINTING OF SMALL NUMBERS** 30 REM**INPUT VALUES OF A AS + -1, +-2.9,+-3.** 40 INPUT A 50 LET N=0 60 PRINT A*(10**N) 70 LPRINT TAB 10;A*(lQ**N) 80 LET М-М-1 99 GOTO 60 J5: Rounding ROUNDING UP The computer will print out computed values to an accuracy of 8 significant figures, ignoring leading zeros. Digits after the 8th significant one will be rounded up. For example, if we key in (as a direct command, followed by NEWLINE/ENTER): 11% PRINT 0.111111111 + 0.888888888 the answer on the screen is 1.Try PRINT 0.0000111111 showing 10 digits can be held exactly. Adding a one on the end forces the use of the E notation. ROUNDING DOWN The INT function returns the nearest integer of the expression X, which is < = X, i.e. it rounds down. e.g. INT 3.9= 3 INT -2.8- -3 INT (4 -8.7 +0.8)= - 4 Try printing these functions. Notice that for negative numbers - 6 is less than - 5, and so on. To round to the nearest integer add 0.5 to the number first: e.g. INT (3.9+0.5) = 4 INT (2.4 + 0.5) 2 ІМТ(-1.7-0.5)- -2 ІМТ(-2.3-0.5)- -2 Notice this assumes that 0.5 rounds (о 1. INT (1.5-0.5) = 2 INT (-1.5+0.5)= -1 Notice we don’t have to enter the zero before the decimal point on the computer (though it doesn’t matter if we do), it’s in that form here for clarity. J6: How Numbers are Handled All computers perform their arithmetic and processing using the BINARY NUMBER SYSTEM In the binary system only two digits are used, 1 and 0. A group of 8 binary digits (bits) is called a BYTE, and we communicate with the computer in Decimal Notation. This is rather more convenient than using Binary. Conversion from Decimal to Binary and vice versa is thus necessary and occurs inside the computer. One BYTE is equivalent to a single character of the computer’s character set. A byte represents a number between 0 апа 255 (decimal). ‘This is why the character codes are in this range (see Section P). A group of 8 zeros and ones can have 2° ( = 256) different states. A digit or number is represented by one or several bytes according to its context in the computer. 115 A character input to the computer or output to the screen or printer is held in one byte. Program line numbers, which are whole numbers 1 to 9999, are held in two bytes. Numbers are held in a form which occupies five bytes. The point to be noted here is that conversion from decimal to binary and back is involved in the operation of the computer, and this conversion is not always exact. This must be allowed for in certain circumstances, especially where the computer is asked to check whether two numbers are equal. A difference in the binary form of the number, however small, will cause the computer to decide they are not equal. In testing two numbers for equality, therefore, if non-integer values have been utilised, and the value of one number arrived at by calculation, the equivalence check should be replaced by assessing the difference. A statement such as: IF ABS(A - В) < 1E-4 THEN... which checks that the difference between the numbers is less than .0001, сап be used instead of IF = B THEN ...., if either A or B has been calculated. The forms in which numbers are held in the computer are considered in detail in Section U — the Computer Memory. J7: Function We define a FUNCTION as Y = F(X) ‘Y equals some function of X, F(X)’ A function is the mathematical relationship between two variables X and Y such that for each value of X there is a unique value of Y. Y takes the function value and is the DEPENDENT VARIABLE. X is the ARGUMENT - the INDEPENDENT VARIABLE. F is the function NAME, e.g. square root, sine, natural logarithm. In a program statement we write, for example: 100 LET Y SOR(X) The argument X can be a single variable, a number or an expression. If X is a single variable or a number it does not need brackets. If it is an expression it requires brackets so that the expression is evaluated before the function is applied to it (so that SOR 9 + 7 gives 10, whilst SOR (9 + 7) gives 4). For example: 100 LET Y = SOR 9 100 LET Y = SOR(B**2—4*A*C) (B42 on the Spectrum) We see that a function is a mathematical operation which gives a number. It is treated in BASIC as a numeric expression, with priority I. 116 The standard mathematical and trigonometric functions are important timesavers for programmers. They are the same as the function keys on scientific calculators. Other functions (utility functions) control or monitor the handling of data by BASIC rather than perform mathematics. If the functions were not available in BASIC we would need to write separate programs to undertake their tasks every time we had need of them! J8: List of Functions used in Sinclair BASIC In this list of functions X is the argument. X is a variable, a number or an expression. If an expression, X must be in brackets. Each of the individual functions will be discussed in more detail later in this section. 1. Standard Mathematical Functions: ABS (X) - gives the absolute value of X EXP (X) - gives e", value of e raised to the power X INT (X) -gives the largest integer < = X, i.e. rounds down LN (X) -gives natural logarithm (value of log. X) SOR (X) -value of V X or X* (X positive) PI -3.14159265 i.e. value of n, PI, which is how it prints on screen SGN (X) -gives sign of X, i.e. whether X is + ve, – ve or Zero. 2. Trigonometric Functions SIN (Х) - value of sine X (X in radians) COS (X) -value of cosine X (X in radians) TAN (X) -value of tangent X (X in radians) ACS (X) -angle in radians whose cosine is X -arccosine Х( - 1 «- X < = 1) ASN (X) -angle in radians whose sine 18 X -arcsine X ( -1 <= X < = 1) АТМ (X) -angle in radians whose tangent is X - arctangent X 3. Special Mathematical Functions RND A random number generating function; gives the next pseudo random number N from a fixed series of random numbers (0 < = N < 1). RAND ( RAND 0) starts the sequence of random numbers in an unknown position. RAND N (ü0 < = N < = 65535) makes RND always return to the same value, if N is the same. 117 4. Character and String Functions CHR$(X) 0<-Х <=255 returns the single character whose code is X. CODE A$ When applied to the string A$, it returns the code of the first character in the string or 0 if the string is empty (null string). LEN A$ Returns the number of characters in the string. VAL A$ Turns a string in number representation into the number for calculation (e.g. A$ = “12.4”, VAL А$ = 12.4). STR$ М Turns the number N into the string “N”. 5. Printing Functions used in the form PRINT F(X) TAB (X) Places the print position in column X. If X>32 then column number is the remainder when X is divided by 32. If it involves back spacing, goes on to next line. Rounds X to nearest integer. AT (X), (Y) Starts printing at line X, column Y бжделлбе21. = Y <= 31 Rounds X and Y to nearest integer. 6. Special Functions INKEY$ No argument. Reads keyboard and senses what key is being pressed at that time. Returns key being pressed as a string, e.g. “А” or ‘‘8’’. If no key is pressed the null string is returned. PEEK X 0 < = X < = 65535 Returns the value of the byte at address X in RAM or ROM memory. USR N Returns the contents of a pair of CPU registers after running a machine code program from address N. N.B. For the Spectrum’s additional functions, see Section W. The above functions, common to both the ZX81 and the Spectrum, are the ones used in the main body of the text. J9: The Function Characters Each of the functions in Sinclair BASIC is represented on the keyboard as a single character word. You don’t have to type the function name letter by letter (if you try to it won’t work), just press the particular function key. Each function character has a special character code and is part of the computer’s character set. Each of the Function 118 characters on the ZX81 is situated at the same position on each key, i.e. bottom outside. To obtain the function the ZX81 must be im FUNCTION MODE, with the F-cursor on the screen. On the Spectrum, all functions are obtained in the Extended mode with the E-cursor on the screen (for further details see Section W1). All FUNCTIONS treated here are in green above the key on the Spectrum, with the exception of ASN, ACS, ATN which are in red below the associated SIN, COS and TAN functions, although they are still obtained in the E-mode. The FUNCTION/EXTENDED MODE only lasts for one function. To obtain successive functions this mode must be repeatedly entered. J10: The Function Character Set Character Code Code (7Х81) (Spectrum) SIN 199 178 COS 200 179 TAN 201 180 INT 207 186 RAND 64 249 STR$ 213 193 CHR$ 214 194 CODE 196 175 PEEK 211 190 TAB 194 173 ASN 202 181 ACS 203 182 ATN 204 183 SGN 209 188 ABS 210 189 SQR 208 187 VAL 197 176 LEN 198 177 USR 212 192 LN 205 184 EXP 206 185 AT 193 172 INKEY$ 65 166 NOT 215 195 п (PI) 66 167 These are the function characters as represented on the ZX81 keyboard. NOT is dealt with in Section R and INKEYS in Section K. Note that ARCSIN, ARCCOS and ARCTAN are used on the ZX81 keyboard but print as ASN, ACS, АТМ, and п prints as РІ. J11: The Standard Mathematical Functions ABS (X) Returns the absolute value or modulus of the value X. X may be a number, variable or expression. ABS(X) gives us the positive value of X. For example: 10 PRINT ABS( - 3.7) gives 3.7 10 PRINT ABS (4) gives 4 Exercises Key in and run this program: 10 INPUT A 20 INPUT B 30 PRINT TAB 3;A; TAB 10;B 40 PRINT TAB 3; ABS (A - B) 30 GOTO 10 Input positive and negative values for A and B. Now change line 40 to: 40 PRINT TAB 3; ABS (A*B) and input some more values. Try replacing the * with ** ( ^ Spectrum), or using ABS (SOR А). N.B. ABS (- 3**3) , or expressions in similar form will not work as the ** ( ^ Spectrum) operator only works for positive first operands. EXP (X) Where X is a number or an expression EXP (X) gives the value of the constant e raised to the power of the value of X e — 2.7183 e.g. 10 PRINT EXP (3.4) i.e. 10 PRINT (2.7183* *3.4) (2.7183 1 3.4 on Spectrum) The function EXP is the inverse to LN. Exercises 1 Using log tables write a program to check the values of e* given in the log tables. 120 2 Write a program which will calculate O from the expression: Q = Qo.e-"* (In BASIC Q = QO* ЕХР(-Т/К“С)) If you know anything about electricity, you might recognise this expression. 3 Key in this program. It calculates a value for e from the formula: e=(1+1/N)**N (^N оп Spectrum) where N is very large. Spectrum users should replace ** by # in lines 30 апа 40. 10 REM “VALUE OF E" 20 ІЕТІ- 1 30 LET N=10**I [^Spectrum] 40 LET E=(1+1/N)**N 50 PRINT TAB 1;N;TAB 12;E 60 LET I=I1+1 70 IF l=5 THEN STOP 80 GOTO 30 LN (X) Gives the value of the natural logarithm. LN (X) = Log, (x) Note that log, (X) (common logarithm) = ( LN(X) )/( LN 10 ) The LN function is the inverse of EXP So: If EXP (X) = Y Then (X) = LN(Y). LN (Y) is the natural logarithm of Y. The antilog is EXP(LN(Y)). The normal log operations can be used if appropriate, as with common logs. For example EXP(LN (X) + LN (Y)) gives the product of X and Y. Exercises 1 10 LEFY=1 20 PRINT TAB 3;Y; TAB 10; ЕХР (LN Y) 30 LET Y=Y+1 40 GOTO 20 Key in and run this program which proves the relationship between the EXP and LN functions. 2 Change 30 to: 30 LET Y = Y*1@ and run again. SQR (X) The function SQR returns the square root of (X), V (X) or Х95, For example: 121 PRINT SQR 9 gives 3 PRINT SQR 23 gives 4.7958315 PRINT SQR (19 + 17) gives 6 PRINT SOR (ABS - 25) gives 5 SGN (X) SGN (X) returns + 1 if (X) is positive, 0 if (X) is zero, — 1 if (X) is negative. SGN is short for Sign or Signum (Signum doesn’t sound like Sine). For example: SGN 23 gives 1 SGN - 5 gives - 1 SGN (3 – 3) gives Q SGN 1 gives 1 SGN (25 - (2*23)) gives — 1 п PI T (which prints on the screen as PI) is a function which has no argument. It returns the value of r as 3.1415927. 3.1415927 is what prints on screen for PI. How would you test whether the computer held any more digits of PI in memory? What happens when you take away 3 from PI? J12: Trigonometric Functions SIN COS TAN The functions SIN (X), COS(X)and TAN(X) give the value of the sine, cosine, and tangent of the number or expression X, which is an angular measure. X must be in RADIANS. We normally express angles in DEGREES. PI = өй. 9... dE. Š 1 DEGREE 180 RADIANS (1 180 radians) To convert degrees to radians multiply by PI/180. For example, if Y is our measure of angle in degrees then: SIN (Y*PI/180) gives the correct value of Sine Y. Exercises 1 Generate a table of values for SIN (X), COS (X) and TAN (X) 122 for every 20 degrees in the range 0 — 360 degrees. 2 Write a program to verify the trigonometric formula: SIN(XX)+COSXX) =1 1+ TAN XX) =SEC*X) 3 Write a program to calculate the area of a triangle from a knowledge of the length of 3 sides and an angle. ACS ASN ATN The functions: ACS (X), ASN (X), ATN (X) give the arc cosine, the arc sine and the arc tangent, respectively, of (X). The returned value is the angle in RADIANS for which the cosine, sine or tangent would be given by the value of (X). To get the angle in degrees multiply by 180/PI e.g. Y = 180/PI*ACS(X) gives arcsin (X) in degrees. Notice these functions print as above, but appear on the ZX81 keyboard as ARCSIN, ARCCOS, ARCTAN. J13: Special Functions Random number generators are useful for games and simulation in statistics. The numbers generated are part of a very long sequence of numbers (there are 65536 of them) and are in fact only ‘pseudo- random’, but good enough for our needs. RND RND gives a random number greater or equal to zero but less than one. 10 LET A = RND assigns a number in the range 0 < = N <1 to the variable A. Notice RND has no argument. If we key in PRINT RND we get a number like .0011251904 or 0.43715682 which is eight or ten digits long and is not much use to anybody in this form. We need to be able to generate random numbers within a useful range, according to our purposes: 1. To obtain a Random Number 0 - 9 To obtain a random number from 0-9 we must multiply our 123 function by 10 and take the integer value. i.e. PRINT INT (RND*10) RND*10 gives random numbers between 0.00000000 and 9.9999999, IN'T( ) will round these values down to integers 0 to 9. 2. Numbers 1-10 Although @ to 9 gives us ten values the range 1 to 10 would be more useful. This is obtained by adding one to the RND function: PRINT INT (RND*10 + 1) Suppose we wanted random numbers generated for simulating a dice roll, we would use: PRINT INT (RND*6 + 1) 3. Random Numbers for a Card Game There are 4 suits, with 13 cards per suit = 52 cards. So if we used: PRINT INT (RND*52 + 1) we could select cards at random. Think about how you could identify the suits and not deal the same card twice. 4. ‘Tossing a Coin There are two outcomes, head or tails, so: 10 LET A= INT(RND"?2 + 1) 20 IF A=1 THEN GOTO 50 aD PRINT “TAILS” 40 GOTO 10 50 PRINT “HEADS” 60 GOTO 10 This program will toss coins until we use BREAK. RAND N RAND is a keyword and is used for controlling the randomness of RND. The computer has a fixed sequence of 65536 jumbled up numbers. RAND N will start RND reading numbers from the Nth number in the sequence. Key in and run this program to prove the above: 10 RAND 7 20 LET Ce=1 30 PRINT RND 40 LET C-C-«1 124 50 IF C<6 THEN GOTO 30 60 GOTO 10 Not amazingly random after all! Exercises 1 Write a program which throws three dice and prints the values thrown across the screen. 2 Write a program to check that the number generated by RND using RAND N is given by RND = (75*(N + 1) - 1/65536). 3 Modify the coin tossing program to count the number of times heads or tails have come up (you need one variable for each). When you've stopped the program by pressing BREAK, you can then access the values by keying in PRINT HEADS, or whatever your variable name is, as a direct command. 4 Write a program to print four groups of three random numbers in the range 1 to 52. 125 SECTION K: STRINGS K1: Strings A string is a set of characters enclosed by quotation marks, e.g. “THIS IS A STRING” or the null string (no characters Typical Strings: “BALL OF STRING" “JANUARY 1ST 1982” “URGHH!” “FAB ** — +/!3” E " (String of spaces) 1234” ore (Null string) Computers handle two kinds of DATA: NUMERIC - numbers ALPHANUMERIC - names or TEXT. The way a computer deals with text is called STRING HANDLING. Strings deal with ALPHANUMERIC information. The sequence of alphanumeric characters is handled in a string as a single unit of data. Characters are defined as LITERALS when placed inside quotes “> They are taken literally to represent themselves. Strings are therefore literals. Characters are IDENTIFIERS where they are not enclosed in quotes. Thus, for example, A represents or identifies a numeric variable and A$ identifies a string variable. Strings can either be of FIXED LENGTH-e.g. always 10 characters long - or VARIABLE LENGTH. The fixed length is determined by the string dimension instruction: DIM A$ (N) where N is the length in characters. Characters which cannot be used in strings A string cannot contain a character that is a line terminator: NEWLINE (ENTER) or TAB. Nor can it contain any of the following: EDIT GRAPHICS RUBOUT (DELETE) FUNCTION BREAK ee (single quotes) 126 All other characters in your computer’s character set can be used. Run the program which checks this: 10 INPUT A$ 20 PRINT A$ 30 GOTO 10 Now try and input some of the above characters. Examples of the sort of text we may want the computer to handle are: — a telephone directory - names and addresses - a timetable - expenses details Computers store all this textual information as strings. String manipulation by the computer would, for our first example, need to deal with: creating the telephone directory sorting the names and numbers into the correct order searching the directory for somebody's number revising the directory, i.e. updating or adding an entry printing out the directory in whole or part. K2: Quotes and Quote Image QUOTES All strings are enclosed in quotes ‘‘’’ when: (1) They are to be INPUT from the keyboard, as in a program line such as: 10 INPUT A$ . When the line is run the cursor оп the screen appears already enclosed in quotes |1 |”. You key in just the characters wanted in the string. (2) When used in programs with the PRINT instruction, e.g. 20 PRINT ‘‘STRING’’. (3) When assigned in a program to a string variable, e.g. 30 LET А$ = * STRING". THE QUOTE IMAGE KEY ON THE ZX81 The QUOTE IMAGE is a special single character on the shift keyboard of the ZX81. 6699 It is used to write ordinary quotes in the middle of a string. eg.10 PRINT "SAY “BELLO” TOO] 127 When the line is run the double quotes will be printed on the screen as single quotes: SAY “HELLO” TOO A special character is needed as two single quotes won’t work. Key in and try to run each of the following lines: 10 PRINT '' SAY “НЕТО”? ТОО” 10. PRINT “БАУ”; "HELLO"; "TOO" 10 PRINT “ SAY "HELLO" TOO" The Spectrum has no QUOTE IMAGE character. Instead, you must put two quotes for every one you want printed. For example, to obtain double quotation marks you type in PRINT“ °>, Single quotes are obtained with PRINT**** ’’’’. Program listings look the same for both machines. K3: String Input On running 10 INPUT A$ the letter cursor appears at the bottom of the screen with quotes round it, prompting you to key in characters for the string = [L] = On the Spectrum this can also be the C-cursor - ‘‘ me STOPPING STRING INPUT When keying in the characters for the string to be input notice that BREAK and STOP have no effect. To escape (1) Use the < key to get outside the quotes. (2) Press STOP, NEWLINE (ENTER) or press | There is a special form of string input, using the INKEYS instruction: INKEYS$ When INKEYS is encountered by the computer it reads the keyboard to determine if a key is being pressed. It does not wait for input like the INPUT instruction. If a key is being pressed it returns the string containing the mode character of the key being pressed. If no key is being pressed it returns the empty string ‘‘’’. 128 The Spectrum returns the mode character with INKEYS$ if in the CAPS mode. We can spend as long as we want before we input a string with the INPUT command, since the cursor will remain on screen. If we want to take advantage of the fact that, unlike INPUT, INKEYS does not require NEWLINE(ENTER) to be pressed, we must arrange a delay. Try this program: 10 PRINT “PRESS A KEY WHEN READY” 20 IF INKEY$-''"" THEN GOTO 20 (no spaces) 30 LET AS-INKEYS$ 40 PRINT “YOU PRESSED ”;А$ Line 20 sends the program back to the beginning of line 20 as long as no key has been pressed. Line 30 makes A$ the single character string returned by INKEY$ when a key is pressed. Due to a design error the Spectrum has far less predictable keyboard scanning using INKEYS than the ZX81. If you type in the program as above on the Spectrum it will work about half of the time. The rest of the time it will skip over line 30. This program will work every time though: 10 PRINT “ PRESS A KEY WHEN READY" 20 PAUSE 0 30 PRINT “YOU PRESSED ”’;INKEY$ Experiment with the two versions to see this problem in action. The action of PAUSE 0 is to stop until a key is pressed. The first key pressed will be the INKEY$. PAUSE will be dealt with later, but remember this quirk of the Spectrum, and this method of dealing with it. The rule is to use PAUSE 0 immediately before INKEYS is used in a program line, to wait for input. Now enter and run this program: 10 PRINT “PRESS 6” 20 IF INKEY$ =“ THEN GOTO 20 (on the Spectrum 20 PAUSE 0) 30 IF INKEY$ = “6” THEN GOTO 60 40 PRINT “FOLLOW INSTRUCTIONS" 50 GOTO 20 60 PRINT “ENDING PROGRAM NOW" 70 STOP Line 20 does the same as before, but line 30 now checks that the right key has been pressed. Notice the 6 must be enclosed in quotes, because INKEYS returns a string. If 6 was pressed, the program goes to line 60. If any other key was pressed, it goes to 40, prints the message, and then is sent back (line 50) to line 20, which waits for another key to be pressed. Games programs, which require interaction, often use INKEY$ in a loop, so that every time the program loops, it checks which key, if any, Is being pressed. 129 K4: Length of a String LEN The length of a specified string A$ is obtained by using the function: LEN A$. The length is given as the number of characters and is the current length of the string. Spaces are included in the length of a string. EXAMPLES 1 10 LET A$=‘‘SINCLAIR”’ 20 PRINT LEN A$ Check that the result is 8. 2 10 LET AS= “А B’’ (9 spaces between A and B) 20 PRINT A$ 30 PRINT LEN A$ Key in and run. 3 10 LET A$- “PRINT” 20 PRINT A$ 30 PRINT LEN A$ Key in the program first with PRINT formed from separate keys, and then change line 10 so that PRINT is formed by pressing the key. Why are the answers different? 4 10 INPUT A$ 20 PRINT A$, LEN A$ 30 GOTO 10 K5: Null Strings A string with no characters is called a null string. For example: LET A$ — 6699 The length of the string is 0. A string which contains spaces is not a null string. A space is a character obtained by pressing [SPACE] . The null string is returned by INKEYS if no key is being pressed. Exercises 1 Key in and run the following program: 10 ТЕГА" 130 20 PRINT A$ 30 PRINT LEN A$ 2 Key in and run this program: іё LET A$e!' ” 20 PRINT A$ 30 PRINT LEN A$ К6: String and String Array Variables AS is a string variable used to store strings. It consists of a single letter (À to Z), followed by the dollar sign. Twenty-six variables of this type are thus possible. The Spectrum accepts upper and lower case letters, but treats, e.g. k$ as the same string as K$. AS(N) is a string array variable or string list variable where N refers to the number of strings in the list. String lists must be dimensioned as an array before the string array variable can be used, by the DIM (DIMension) instruction. Using the array notation, an unlimited number of string variables are possible. Again, the Spectrum accepts upper and lower case letters, but does not differentiate, e.g. b$(N) and B$(N) are the same. Caution: A$(N) can have two meanings in a program. (1) It can refer to the N’th character in a string A$. (2) It can refer to the N'th string in a list or array of strings. In this case the string array must previously have been dimensioned with a DIM A$(N) instruction. K7: String and String Array Dimension STRING DIMENSION DIM AS(N) sets a fixed length of N characters for the string. For example: 10 DIM А$(6) sets a length of 6 characters for the string А8. 131 If strings of length <= < >= > may be used between strings and string variables using the IF... THEN instructions. For example: IF A$ = “YES” THEN GOTO .... IF N$ = B$ THEN PRINT .... IF A$< = B$ THEN GOTO .... When the computer compares strings of characters it does so by comparing the codes of each of the characters in sequence. A string is found to be less than another if it comes first in alphabetic order. If the strings contain numbers we should remember that numeric codes are less than alphabetic (letter) codes. This affects comparisons. (See Section P for the character codes.) Strings are compared in order of characters from left to right. For example: “AS, ЗЫ” "AD S A “А”< “АА” a d.e d “АЗ S “А4” “б” "LE = A “4Д” Key їп and run the next program. Input the strings above plus others you want to try and it will print out their relative alphabetic orders. 10 INPUT A$ 20 INPUT BS 30 IF А5<В5 THEN GOTO 70 40 IF А5-В5 THEN GOTO 99 50 PRINT А5;">";В5 60 5ТОР 70 PRINT A$;"«"; BS 80 STOP 90 PRINT A$;"-";B$ 100 5ТОР 136 This gives us a method for putting names into alphabetic order, like in a telephone directory. We also have a method of searching it, since we can check whether any name in the list is equal to the desired name. We have already used string equality, but here’s another example of string comparison: 10 PRINT "DO YOU UNDERSTAND STRINGS?" 20 PRINT “ANSWER YES OR NO" 30 INPUT А5 40 IF AS = "YES" ТНЕМ GO ТО 70 50 PRINT “THEN READ THE SECTION AGAIN!" 60 STOP 70 PRINT "YOU ARE A GENIUS!" 88 STOP Key it in and run it. Do you understand? The above assumes the use of capital (upper case) letters only on the Spectrum. For lower case letters, these are all after upper case letters in the ordering of strings. So on the Spectrum: AA20 THEN GOTO 100 70 PRINT N+ 7#N so GOTO 50 100 REM **#ЕМП++# Notice that the counting procedure in this program is set up differently again. Line 50 increments the counter. Line 60 checks the counter value. In this case, the IF- THEN statement has the effect of transferring control out of the loop if the counter exceeds 20, with the GOTO 100 statement. The procedure in this case is: 1 Initialise 2 Increment 3 Check counter. If greater than specified value, jump to program end. 4 Body of loop 5 Return to 2. Key in the program. Run it to check it loops exactly twenty times. Then EDIT line 60, to insert: 75 IF N> 20 THEN GOTO 100 and delete line 60. Now run it. It is surprisingly easy to miss the desired number of loops, if you are not careful with the structure of the loop, and the exit conditions. (Change N220 in line 75 to N> = 20 and the program will loop the correct number of times). Different procedures using counters give different program structures. Look at the flowcharts of different counter procedures. Remember that the conditional test can put to use the >, <, >=,<=, = operators, as appropriate. 144 COUNTER FLOWCHARTS Counter = Start Value Counter = Counter + Step of loop Exit Loop 145 Yes Counter = Ətart Value Body of Loop Counter = Counter + Step Counter = Finish Value No Exercise Consider a simple program to work out the squares of the first 20 integers. 19 PRINT "NUMBER", "SQUARE" 20 LET М-й 30 LET N=N+1 40 IF N»20 THEN GOTO 70 50 PRINT N,N*N 60 GOTO 30 70 REM*END OF PROGRAM* 146 The GOTO statement in line 60 will cause the program to loop continuously between lines 30 and 60. This would continue indefinitely but line 40 is inserted so that the program jumps out of the loop when N>20. N is used as a counter. Line 20 initialises N and line 30 increments N by 1 each time the program goes round the loop. Write a program which calculates and prints the square and the cube power of even numbers between 10 and 30. The counter will need to be incremented by 2 each time the loop is executed by a GOTO statement. Write a program which loops 10 times (counter 1 to 10) but uses another counter to print the squares of the ten numbers 5.25, 5.0, 4.75 са. 3.0. L3: For – Next Loops This is a more convenient way of having a program loop. The loop is set up with the FOR... TO ... STEP and NEXT instructions used in combination. The loop goes from the first value to the last value, counting by adding the defined STEP value every time it loops until the exit condition is met. FOR (variable) = (first value) TO (last value) STEP (step) FOR C = (N) TO (M) STEP (X) where C is the counter variable or control variable of the loop and (N), (M) and (X) are numeric expressions. C can be any single letter À to Z. It must not be the same as a single letter numeric variable. It is initialised at value (N). (N), (M) and (X) may take any values, positive or negative, as long as repeated additions of (X) to (N) will reach (M). If STEP is omitted, + 1 is assumed. NEXT C indicates last line of the loop. It adds (X) to C and loops back if the total is less than (M). The program loops back to the line after the line with the FOR - TO - STEP instruction. The FOR - NEXT loop has a fixed procedure, unlike loops formed with conditional GOTO instructions. We form a FOR - NEXT loop in a program like this: 10 FOR F - 0 TO 100 STEP 2 rue: Body of loop 40 NEXT F The FOR statement initialises the loop. 0 is the start value 100 is the stop value F is the counter variable and is initialised as Q STEP 2 is the increment. 147 NEXT F is the last line of the loop and increments the counter F by the STEP value. We can also decrement the counter (decrease it). For example: 10 FOR F=100 TO 0 STEP -2 (where the decrement is 2) The loop will be exited in the first example when Е>100 and in the second when F«0. F will take values 0, 2, 4 .... 98, 100 in the first case, and 100, 98 .... 4, 2, 0 in the second. Any program lines in the body of the loop will be repeated each time the program loops. Try these simple examples: 10 FOR F=2 TO 4 STEP 1.3 20 PRINT F 30 NEXT F 10 FOR F=4 TO -1 STEP -1 20 PRINT F 30 NEXT F 10 FOR F=-2 TO 4 STEP 2 20 PRINT F 30 NEXT F 40 PRINT 50 PRINT "F EQUALS ";F;" ON EXIT" Convince yourself that this doesn’t work: 10 FOR F-2 TO 4 STEP - 1 20 PRINT F 39 NEXT F The next one is an interesting example of the inaccuracies in the computer’s arithmetic: 10 FOR Е-1.2 TO -0.3 STEP - 0.2 20 PRINT F 30 NEXTF The only reason for using F as the control variable is that it is convenient: FOR F can be entered just by pressing the F key twice. You can use any letter, but it is good personal programming practice to use the same letters consistently, and not use these for single letter variables. ‘I’ is often used by programmers as a control variable (I for Integer) but can be confused in program listings. This next example uses N: 10 FORN=1TO15STEP 1 20 PRINT N,N*N 30 NEXT N We can use the value of the control variable in calculation within the loop. Edit STEP 1, so that line 10 reads: 107 FOR N= 1 TO 13 and run it again. STEP may only be omitted for a STEP of + 1. 148 In the program, line 10 allows N to go from 1 to 15 with a step value of 1. That is to say, N takes the values, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 11, 12, 13, 14, 15 each time performing the calculations within the loop. The next program illustrates the use of different values for the step. The value can be positive or negative, integer or non-integer. In the case of decimal increments or decrements there is the possibility of rounding errors if the loop is executed many times — it is therefore advisable to use integer values for the step and divide by the appropriate power of ten, if the loop variable is to be used in calculations. If this were done in the program below, lines 130 and 140 would read: 130 FOR N^ 10 TO 56 STEP 7 140 PRINT N/10; TAB 8; (N/10)**2; TAB 16; (N/10)**3 ( ^ on Spectrum) The program calculates squares and cubes for: a. a Seer, > 31 (line 20) 129, 115, МӘ, „аже 60 (line 70) L, Leds X tone wwe жж 5.6 (line 130) Once again, Spectrum owners should remember that their machine uses the ‘up-arrow’ ( 4) rather than the ZX81’s stars (**) to represent ‘to the power of’. 5 REM "MULTILOOP" 10 PRINT "NUMBER"; TAB 8; "SQ UARE"; TAB 16; "CUBE" 20 FOR N-1 TO 31 STEP 3 30 PRINT N; TAB 8; N**2; TAB 1 6; N**3 40 NEXT М 45 PRINT "ТҮРЕ СОМТ KEY" 50 STOP 60 PRINT "NUMBER"; TAB 8; "SQU ARE"; TAB 16; "CUBE" 70 FOR N=120 ТО 60 STEP -5 80 PRINT N; TAB 8; N**2; TAB 1 6; N**3 90 NEXT М 100 PRINT "ТҮРЕ СОМТ KEY" 110 5ТОР 120 PRINT "NUMBER"; TAB 8; "SQU ARE"; TAB 16; "CUBE" 130 FOR N=1 ТО 5.6 STEP .7 140 PRINT N; TAB 8; N**2; TAB 1 6; N**3 150 NEXT N In this next program the total is represented by T which is initialised equal to zero (line 10). Each time the program goes through the loop the INPUT number is added to T (line 40) so that when the loop (lines 20 to 50) is exited T represents the sum of the ten numbers input. The 149 program evaluates the average by dividing the total by the number of numbers input. 5 REM “АУЕКАСЕ” 10 LET T=0 20 FOR N=1 TO 10 30 INPUT X 40 LET T=T+xX 50 NEXT N 60 PRINT “AVERAGE =”; 7/10 This program illustrates a loop used to print a table. In this case a heading is given (line 70) and this must be outside the loop as it is only required at the beginning. We require all names and ages to be tabulated so the print statement doing this (lines 140, 150) must be within the loop. Finally, we require the average age, which is to be printed underneath, and so the print statement (lines 170, 180) is inserted after the loop has been completed. 10 REM "LOOPS3" 20 PRINT "THIS PROGRAM PRINTS OUT THE NAME AND AGE OF A GROUP OF PEOPLE AND WORKS OUT THE AVERAGE AGE" 30 PRINT 40 PRINT "INPUT NUMBER IN GROU 5Ø INPUT X 60 LET T= 70 LPRINT "NAME", "АСЕ" 80 FOR N=1 TO X 99 PRINT "INPUT NAME" 100 INPUT N$ 110 PRINT “INPUT AGE" 120 INPUT A 130 LET T=T+A 140 PRINT N$,A 150 LPRINT N$,A 160 NEXT N 170 PRINT "AVERAGE AGE-"; T/X;" YEARS" 180 LPRINT "AVERAGE AGE"; T/X;" YEARS" The flowchart of a FOR - NEXT loop would be drawn like this, if we used the standard set of symbols as presented in the unit on programming: 150 BODY OF LOOP No Yes EXIT So for a program like the following: 10 FOR F= 2Т0%5ТЕР.5 20 PRINT F*F 30 NEXT F 40 PRINT “ЕМГ” the flowchart would be like this: 151 However, FOR - NEXT loops are used so frequently that this is a somewhat inefficient way of representing a loop of this type. ‘There is another symbol often used, although it is not a standard symbol, which condenses all the required information. This has the form: 152 OUT OF LOOP END LOOP TO BODY OF LOOP Our example program would be represented like this: L4: Loops of Variable Length The first value, final value and step of a loop may have any values (including variables which may be specified using INPUT). The first example shows a simple program which allows all conditions in the FOR statement to be specified using the INPUT statement. 153 REM "VARLOOP" PRINT "ТҮРЕ INITIAL VALUE" INPUT I PRINT "ТҮРЕ FINAL VALUE" INPUT F PRINT "ТҮРЕ STEP" INPUT S PRINT "X","X**244*X-3" [ ^ Spectrum] FOR N=I TO F STEP 5 LET YsN**244*N-3 [ 4 Spectrum] PRINT N,Y NEXT N It is important in such calculations to avoid the case where 'division by zero' occurs. À simple shown below: example of how this may be done (line 40) is REM "DIVZER" PRINT "X","1/(X-3)" PRINT FOR N=-9 TO 15 STEP 3 IF М-3-0 THEN GOTO 80 LET Y-1/(N-3) PRINT N,Y GOTO 90 PRINT N,"INFINITY" NEXT N The final program in this section illustrates another way of having a variable loop size. The operator may use this program for any number of numbers between 1 and 100. A marker (in this case — 1) is set to indicate when the input is complete, allowing a Jump out of the loop (line 69). This is a ‘dummy value’ — a value not normally entered. (N.B. DO NOT JUMP INTO THE MIDDLE OF A LOOP i.e. a loop must always be entered from the FOR statement.) REM "STDDEV" LET T-0 LET 5-й LET С-й PRINT "THIS PROGRAM WORKS O UT AVERAGE AND STANDARD DEV IATION OF A SET OF NUMBERS" PRINT PRINT "TYPE NUMBERS ONE AT A TIME,TO FINISH TYPE -1" FOR N-1 TO 100 INPUT X IF X--1 THEN GOTO 140 LET T=I+X [ ^ Spectrum] LET S=S+X**2 LET С=С+1 NEXT N PRINT PRINT "AVERAGE IS ";T/C PRINT "STANDARD DEVIATION I S ";SQR (S/C-(T/C) **2) [ 4 Spectrum] 154 The procedure used in this program can confuse the flow of a program and must be used with care. It is useful on occasion, but it is preferable to have only one entry and one exit from a loop. In this program, the loop may be exited from line 90 in addition to the normal termination, when №100. L5: Nested Loops We can place one loop inside another loop, so that every time the program goes through the outside loop, it will perform the inner loop sequence. The inner loop must be entirely within the outer loop. Loops are said to be NESTED one inside the other. Loops can be nested to any depth, i.e. we can have as many loops as we wish, as long as they’re correctly arranged. 30 FOR A=1 TO 6 40 FOR B=1 TO 3 in hs ТТТ Inner Loop | Outer Loop 80 NEXT B | 120 NEXT A To have a third loop correctly placed, it would have to be inside the B (Inner) Loop, or outside the A (Outer) Loop. Be careful to avoid crossing the loops: 10 FOR A=1 TO 6 20 FOR B=1 TO 3 80 NEXT B Programs with wrongly arranged loops will run, without giving an error message, but won't give you the correct answers! To illustrate the use of nested loops, here are two programs. The first evaluates and prints out the squares, cubes and fourth powers of the first ten integers. Each number (N = 1 TO 10) is to be raised to the appropriate power (E=1 TO 4). Note that the loops are correctly nested. 20 FOR N=1 TO 10 Ee FOR E- 1 TO 4 50 NEXTE REM "NEST" PRINT "NUMBER";TAB 7; "SQUAR E";TAB 14; "CUBE";TAB 21;"4T H POWER" 20 FOR N=1 TO 10 30 FOR E-1 TO 4 40 PRINT TAB (E-1)*7;N**E; [^ Spectrum] 50 NEXT E 60 PRINT 70 NEXT N н Qu You will get a printout that starts off like this: NUMBER SQUARE CUBE 4TH POWER 1 1 1 1 2 4 8 16 3 9 27 81 4 16 64 256 The flowchart for the ‘‘NEST1’’ program, using the flowchart symbol for FOR - NEXT loops we have introduced, will look like this: START We can see the sequence of operations by tracing the program. Line 20: Line 30: Line 40: Line 50: Line 60: Line 70: This table uses the ZX81 symbol for exponentiation. Notice how line 40 uses the value of E to format the output. The second example assumes that a company employs three salesmen who keep sales figures for each week. At the end of four weeks the company requires a summary of sales to be printed. Each salesman S (1 TO 3) has weekly takings W (1 TO 4). Notice again that the loops are nested within each other. 30 FOR S=1 TO 3 gon 70 FOR W=1 ТО 4 110 NEXT W 130 NEXT S NAME WEEKi WEEK? WEEK3 WEEK4 JONES 12 16 19 13 BROWN 23 26 29 21 SMITH 31 4 6 39 10 REM *NEZTED* 20 LPRINT "NAME": ТАБ 6: "МЕЕК1 TAB i2:;"WEEKZ": TAB 207 "WEEKS ТАЕ 27: "WEEK4" ЗО FOR 5-1 TO 3 40 PRINT “INFUT SALESMANS NAME - - - - че ча >30 INFUT N$ EO ІРКІМТ N$; 79 FOR W=1 TO 4 SO PRINT "TYPE WEEK "М" SALE 90 INPLIT X 100 LPRINT TAB (7*W-1);X 110 NEXT W 120 LPRINT 130 NEXT $ 157 Exercises Write programs using loops to perform the operations stated: 1 Calculate the reciprocals (1/N), logarithms (LN N) and cubes (L**3 ог L 4 3) of even numbers between 20 and 36 and print them out in a table. An object is dropped and the variation of distance s with time t is given by s=4.9t*. Print a table of the distances fallen for each second from 1 to 15 seconds. Evaluate and print the values of ЗХ? + 4X — 7 for values of X between 6 and 8 in steps of 0.25. Evaluate SIN X for values of X from 0? to 360? in intervals of 10°. Remember you must convert from degrees to radians. Print out the results in two columns. Print a table of the discount at 5%, 10%, 15%, 20% on articles from £100 to £200 in steps of £10. Find the sum of all odd numbers between 39 and 75. Find the sum of the series 1,1,2,3,5,8,... (Fibonacci) to 20 terms. (Each term is the sum of the previous two terms.) Find all numbers less than 50 which can be written as the sum of two squares. (e.g. 13 = 2° + 3°) A ball is dropped from a height of twenty metres and rebounds one-half the height on each bounce. What is the total distance it travels? Assume the ball stops bouncing on its hundredth bounce. 158 SECTION M: PLOTTING M1: Plot and Unplot The screen size is the same on both the ZX81 and the Spectrum. It is divided into 24 x 32 character cells in the same way for printing on the screen. The bottom two lines are reserved for use by the computer. However, the plot screens of the ZX81 and Spectrum differ. The principle is the same, that of dividing up the screen into small squares, each of which can be blacked in separately, but the Spectrum has a higher resolution plot screen than the ZX81. This means that the screen is divided up into smaller squares (called pixels, short for picture elements) on the Spectrum. The Spectrum has extra graphics commands not available on the ZX81 which make use of these pixels, some of which are mentioned in this Unit, but are dealt with fully in Section W. The commands are also different on the two machines, so we will describe the two separately before dealing with some of the uses of these commands. Spectrum users should note the principles of plotting as presented here (even where we note that a particular process is easier using one of the Spectrum graphics commands, since it is the principles that are important, and can be extended to more complex tasks), and not just feel superior to the ZX81 user, who has no access to CIRCLE or DRAW! On both machines each pixel is specified by X,Y co-ordinates. Thus, on the ZX81 (0,0) is the bottom left-hand corner and (63,43) is the top right-hand corner. There are 4 pixels in each character cell. PLOT X,Y - blacks out the picture element (pixel) with co- ordinates X,Y. UNPLOT X,Y - blanks out the pixel with co-ordinates X,Y. The PLOT co-ordinates run from 0 to 63 across the screen left to right (X co-ordinates) and from 0 to 43 up the screen bottom to top (Y co-ordinates). As a memory aid, remember that X is ‘a cross’, and X before Y. It is a simple matter to print horizontal and vertical lines. This program plots a horizontal line across the screen: 19 FOR N = 0 TO 63 20 PLOT N,20 30 NEXT N See if you can write a program that plots a rectangle. Each of the character cells on the Spectrum’s screen has 8 x 8 = 64 pixels, and there are thus 176 in any column up the screen and 256 in any line across the screen. Once again specifying each pixel with X and Y co-ordinates, 0,0 is the bottom left-hand corner and 255,175 is the top right-hand corner. Whilst PLOT X,Y on the Spectrum blacks in the pixel element in 159 exactly the same way as on the ZX81, there is no UNPLOT statement on the Spectrum. To erase the dot again the OVER 1 facility is used. Thus, to erase at X,Y you must enter a multiple statement line. OVER 1: PLOT X,Y - blanks out the pixel at co-ordinates X, Y Although it is perfectly possible to plot a horizontal line to the screen using a program similar to that used on the ZX81: 10 FOR N=8 TO 255 20 PLOT N,20 30 NEXT N it is far simpler on the Spectrum to use the following type of formulation: 10 PLOT 0,20: DRAW 255,0 It is also possible to get some semblance of motion. ‘The program below moves a dot across the screen: On the 2Х81 On the Spectrum 10 FOR N= 0 TO 63 10 FOR. N= 0 TO 255 20 UNPLOT N - 2,20 20 PLOT OVER 1; N - 2,20 30 PLOT N,20 30 PLOT N,20 40 NEXT N 40 NEXT N It 1s possible to construct simple shapes using PLOT. Here is a ZX81 routine to draw a (somewhat stylised) dog: 10 LET X=0 20 LET Y=10 38 PLOT X,Y 40 PLOT X+1,Y-1 50 FOR N=2 TO 4 68 PLOT X+2,Y-N 70 NEXT N 80 PLOT X+3,Y-2 990 PLOT X+4,Y-2 100 FOR N=1 TO 4 110 PLOT X+5,Y-N 120 NEXT N 138 PLOT X*6,Y 140 PLOT X+7,Y-1 It can sometimes be worth remembering that the PLOT pixels are not exactly square. The visible variation from square will depend on the type of plotting being done, and the particular TV screen in use. It is worth drawing what should be a square on the screen, and simply measuring the variation with a ruler. Try running this program, and do this for different areas on the screen, so that you can check if the variation is constant. Note the double loop, which is often useful in PLOT routines. On the ZX81 On the Spectrum 10 FORF-10 TO 30 10 FOR F=10TO 100 20 FOR L= 10 TO 30 20 FOR L=10 TO 100 30 PLOT F,L 30 PLOT F,L 40 NEXT L 40 NEXT L 50 NEXT F 50 NEXT F 160 The variation from square on the screen is typically in a ratio between 1.1:1 and 1.2:1 (across screen/down screen). This means a ‘square’ that looks square will need to be 10 pixels across and either 11 or 12 pixels down. Most PLOTting is done utilising loops. To PLOT a circle we need to choose a suitable STEP value for a loop that runs either from @ to 360 (degrees), or 9 to 2 PI (Radians). We also have to set a centre to give us a circle where we want it, and a radius such that it will fit the screen. For a circle in degrees, code in this program: On the ZX61 On the Spectrum 10 FORD=0TO360STEP10 10 FOR D=0 TO 360 STEP 2 20 LET R=D*PI/180 20 LET R=D*PI/180 30 LET X=30+20* COSR 30 LET X=120+80* COS R 40 LET Y=20+20* SINR 40 LET Y=80+80* SINR 50 PLOT AY 50 PLOT X,Y 60 NEXT D 60 NEXT D Line 2@ converts to radians, in which all the trigonometric functions of the computer work. Line 30 calculates the horizontal component, and line 40 the vertical. The SIN and COS functions are multiplied by 20 (80 оп the Spectrum) to give a radius of 20 pixels. The centre is set for the 7Х81 at pixel 30, 20, and for the Spectrum at pixel 120, 80. In most cases, it is convenient to consider the PLOT screen to be 60 x 40 pixels (ZX81), rather than 64 x 44, in order to set scales and position plots оп the screen, and 240 x 160 similarly for the Spectrum. Having set the basic values, we can introduce variations within the loop into the above program. We can calculate the radius value and get a spiral plot. Alter the program to: For the ZX81 For the Spectrum 10 FORD-20 ТО 360 STEP10 10 FORD-0 TO 360 STEP 2 20 LET Z = D*PI/180 20 LET Z= D'PI/180 30 LET R-Z*3 30 LET R-Z*10 40 LET X = 30 + R*COS Z 4) LET X = 120 + R*COS Z 5) LET Y=20+R*SIN Z 30 LET Y=80+R*SIN Z 60 PLOT X,Y 68, PLOT Q<, Y 70 NEXT D 70 NEXT D Calculating additional values, all within the loop, and using the loop values as a basis, provides complex shapes fairly easily. Alter the first three lines of the program: For the ZX81 For the Spectrum 10 FOR D = 0 TO 360 STEP 5 10 FOR D-0 TO 360 20 LET Z=D*PI/180 20 LET Z=D*PI/180 30 LET R= 20*SIN(Z*4) 30 LET R =60*SIN(Z*4) RUN it. From a simple circle, we now have the basis for a polar graph plot and can identify a scale of values for PLOTting that will fit the screen. Similarly using parametric equations for the ellipse on the ZX81, X goes from 10 to 50 as COS goes from - 1 to 1 and Y from 10 161 to 30 as SIN goes from — 1 to 1 round the circle. Notice this uses radians directly (2*PI radians = 360 degrees). Spectrum plot points are multiplied by 4. For the ZX81 10 FOR N-0 TO 2*PI STEP PI/20 20 PLOT 30 + 20*COS N, 20 + 10* SIN N 30 NEXT N For the Spectrum 10 FOR N =0 TO 2*PI STEP PI/180 20 PLOT 120 + 80 *COS N, 80 + 40*SIN N 30 NEXT N Try altering the multiplication factors in line 20 for different ellipses. Alter the STEP value to get a continuous line. Of course, on the Spectrum a simple CIRCLE statement enables us to achieve the same result demonstrated in our first example much more quickly. For instance: CIRCLE 128,88,50 will draw a circle of radius 50 pixels with its centre in the middle of the screen. This is included with the additional Spectrum functions in Section W. Note however that the calculated circles are more accurate than the ones drawn using CIRCLE, but a lot slower to PLOT! Exercises 1 PLOT the extreme corner pixels, measure the rectangle and use the computer in command mode to calculate the proportions of a pixel rectangle on your screen. 2 PLOT a circle, using radians directly, without a degree conversion, with another circle, half the radius, inside. 3 PLOT a more accurate circle with allowance made for the pixels being non-square, by altering the multiplication factors for either COS or SIN. 4 Change the spiral routine to produce a double spiral (i.e. going round the circle twice). 5 Experiment with the rosette producing program. Alter the values of R in line 30 by changing the factor by which Z is multiplied. Try Z**2 (Z^42 on Spectrum) and similar expressions. M2: Graph Plotting Simple graphs may be plotted using the PRINT functions already encountered. The following program illustrates its use for drawing a histogram. Lines 20 to 70 allow twelve values to be input and make Z the largest value input. Lines 90 to 150 plot out the histogram allowing the maximum value (i.e. Z) to be 25 columns long and all the others are drawn in proportion. 162 10 REM "HISTO" 20 DIM M(12) 30 LET 2-0 40 FOR N=1 TO 12 50 INPUT M(N) 60 IF M(N) > 2 THEN LET Z=M(N) 70 NEXT N 80 REM **PLOT** 90 FOR N-1 TO 12 100 PRINT N;TAB 4; 110 FOR L-1 TO M(N) STEP 2/25 120 PRINT "*"; 130 NEXT L 140 PRINT 150 NEXT N Result: LKR KKK ke e e e ke e e ke e e e e e Х 2 **k* d kk ke ke e ke e e e e e 4 kkKKKKKEK 5 ЖЖЖЖ Ж б á kkkkkkkkkkkkkkkkkkkkkkkk 7 ж 0 kkkKKKKKKKK О KkKKKKKK 10 ****#****@**@**%*m*@**w**w** 11 ****x* 12 *********@**@*w* The STEP value in the program above is a SCALE FACTOR. The use of a suitable scale factor is needed in most graphical routines. Here is another version of a barchart program that identifies the scale factor and uses it to multiply the values to be plotted out using the asterisks. (The graphics characters can be put to use to draw solid bars, where the asterisk is used here.) 10 REM *BARCHART* 20 PRINT "ENTER MAX VALUE" 30 INPUT M 40 LET SCALE-25/M 50 PRINT "ENTER VALUES (MAX 2 0) ENTER -1 TO FINISH" 60 PAUSE 150 70 CLS 80 FOR F-1 TO 20 90 PRINT AT 21,0; "INPUT VALUE ";F 100 INPUT V 110 IF V--1 THEN Goro 190 120 PRINT AT F,0; V 130 PRINT AT F,5; 140 LET V-V*SCALE 150 FOR T-1 TO INT (V4.5) 160 PRINT "*"; 178 NEXT T 180 NEXT F 190 PRINT AT 21,0;" " 163 The identification of scale factors to produce the best plot possible within the avallable X,Y values on the screen is vital in all plotting routines. The plotted functions have to be plotted on the biggest scale that will enable them to fit the screen. This program fits the screen without any problem: ZX61 10 FOR X =0 ТО 60 20 PLOT X,SQRX 30 NEXT X Spectrum owners should bear in mind that each pixel you can PLOT on the Spectrum is a quarter as wide and a quarter as high as those on the ZX81. Thus, as a general rule, you should allow for a factor of four when working with ZX81 scales, as shown in this discussion of scaling factors. In the program above, for example, the first line would read FOR X =0 TO 246. The program above does not give the best illustration of the shape of the curve, although it has the X,Y scales the same (one pixel = 1). Changing line 20 to: 20 PLOT Х;2“5ОКХ gives a better graph. It is obvious, in this instance, that we could increase the scale factor — in this case the number by which we multiply SOR X to get the Y value —to 5, and the graph would still fit the screen. But if we try this program (do!): ZX61 Spectrum 10 FOR X =0 TO 60 10 FOR X-0 TO 240 20 PLOT X, X*X 20 PLOT X,X*X 30 NEXT X 30 NEXT X we would only get a few points plotted before the computer stops with an ‘integer out of range’ error code. It is obvious that the maximum value in this case will be 60 x 60 = 3600 (7Х81) and 240 x 240 = 57600 on the Spectrum. So if we used: 20 PLOT X, X*X/100 20 PLOT X, X*X/400 the highest value for the Y pixel would be 36 on the ZX81, which makes use of most of the screen. (For the Spectrum it would be 144.) In most cases, however, it 1s not so easy to see what the scale factors should be. We have a 44x64 screen to use on the ZX81 and а 256 x 176 screen on the Spectrum, and so in general, for positive values only, suitable scale factors are given by: ZX81 Spectrum (X axis) 65 259 Largest value of X Largest value of X (Y axis) 43 175 Largest value for Y 164 Largest value for Y For a full range plot of a function that takes positive and negative values, for example SIN, we have to set a scale factor which refers to the screen available for use above and below the pixel Y value taken as zero. To give an example, for a SIN function, taking values between +1 and -1 we set the zero line as Y=20 (7Х81) or Y = 80 (Spectrum). We then need to find a scale value such that the Y values vary between 20 above and 20 below this line (80 above and below for Spectrum) as SIN varies between + 1 and - 1. Again, it is obvious that we need to use a line like: 2Х81 Spectrum 20 PLOT X, 20 + 20*SIN X 20 PLOT X, 80 + 80*SIN X To get a single full range curve we need X to vary from 0 to 2PI radians, so we can use: 10 FOR X -0 TO 2*PI STEP 2*PI/60 20 PLOT X, 20 + 20 *SIN X [80 + 80 *SIN X on Spectrum] 3 NEXT X for full screen use. (Remember 2PI radius = 360°.) Up to now, although you have been told about the co-ordinates of the PRINT and PLOT screens, we have treated the use of PRINT and PLOT as two separate areas. Since the PRINT and PLOT co-ordinate systems refer to the same screen, the two may also be used in concert, but care must be taken. Confusion is likely to arise between the numbering systems, not so much in the numbering across the screen, but in the Y plane, where pixels count 0-43 (@-175 оп the Spectrum) upwards, and the print lines 0-21 downwards. Pixels are coded X,Y, across and up, print positions L,C, down and across. The screen grids for printing and plotting are reproduced here for both the ZX81 and Spectrum. 165 THE ZX81 PRINT AND PLOT SCREEN You cannot PRINT or PLOT on the bottom two lines. «—— Lines An example: this is Columns —— the pixel (57,32) 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 x 48 | 50 | 52 Pixel x-coordinates PHT Pixel y-coordinates ----ь 166 An example: this is the pixel чыш | = E = О Q ESI q — s3}2uIp1009 Á |axid 6/1. ¿9L 861 161 ЕРІ SEL 721 GLL Lit EOL 96 ZB 62 14 БӨ SS Zh ФЕ IE EE Gt и 891 091 ZSL vti 961 821 001 Zit VOL 96 88 08 22 v9 95 BH OF ZE vC 9 8 0 38 еу ~ <+ š бәш| OM} uuolloq eu) uo | 1014 10 LNIHd Aijeuuou 1ouueo под N33439S 10 ld '? Іміна WNYLOAdS JHL Pixel x coordinates ——— р> It is useful, when both PRINTing and PLOTting on the screen, to work with one screen grid first, and then add the other grid. As an example, consider graph titles. We could, to get a title for a printout of a graph, use a direct command: PRINT ‘‘GRAPH OF Y = X**2/100’’, then use COPY, BREAK the COPY routine after the first lines printed, then PLOT the graph with our program and COPY that, but it’s not very elegant. We want the title on the screen with the plotted graph. We can first set the PLOT routine, for example: ZX61 Spectrum 10 FOR N=0 TO 60 10 FOR N-0 TO 250 20 PLOT N, N*N/100 20 PLOT N, N*N/400 30 NEXT N 30 NEXT N By inspection, after RUNning the routine, we can add a title where it will not interfere with the PLOT. 40, PRINT AT 0, 35: “27 50 PRINT AT 1,0; “Y =X 7100 This gives us a screen with everything on it, with the bonus of using standard notation for X°, not the BASIC’s ** (fon Spectrum) notation. A different function might require the PRINTed strings to be placed elsewhere. Exercise Write a program that will calculate the pixel co-ordinates of any PRINT square (character cell). Input L and C (for Line and Column), with suitable prompts erased by an empty string, and output “Piel” s Х; 4)”; Ү; 16 top right’’, etc. For the ZX81, output the four pixels in any specified character cell. For the Spectrum, output the X,Y co-ordinates of the four corner pixels. 168 SECTION N: SUBROUTINES N1: Subroutines A subroutine im BASIC is a program module performing an allotted task and is entered using a GOSUB statement. The section of program Is completed and exited by a RETURN statement which sends the computer back to the line following the GOSUB statement. A subroutine must only be entered via a GOSUB statement and exited by a RETURN statement. Two instructions are used to create subroutines. GOSUB (line number) - transfers control to the specified line number RETURN —leaves subroutine and returns control to the line immediately after the GOSUB instruction which transferred control to the subroutine. Spectrum users have probably noted that their machine prints GO SUB with a space. Here is an example of the program structure for these instructions: IBS ,.. 110 GOSUB 500 --------(1) Таб ... TO uw 140 GOTO 600 520 REM *SUBROUTINE* (3) 5318 vs 520 ... dy (4) 539 wns 540 RETURN 600 STOP (1) GOSUB - goes immediately to line indicated (500) (2) Continues program (lines 500-540) until RETURN reached (3) Program returns to line 120 (line immediately after GOSUB statement). (4) Itis vital to ensure that a subroutine is not entered accidentally when writing the program. Note that line 140 does this by using a GOTO statement to bypass the subroutine. Line 600 may continue the program, or be a statement such as REM*END OF PROGRAM”. It is a useful practice to end a program at the highest line number, which indicates successful completion of the whole program. The alternative, stopping the program with a line 140 STOP, could also be used. 169 Subroutines are often used for repeated procedures and may be thought of as separate program structures: MAIN ROUTINE SUBROUTINE 100 114 GOSUB 500—~>|500 REM SUBROUTINE * 120 -&——— 510 130 520 14) GOSUB 500— 1530 REM * END OF SUBROUTINE * 150 =< 540 RETURN 160 The computer stores the line number of the GOSUB instruction (whereas it doesn’t with a GOTO). The RETURN instruction transfers control back to the line number after the /atest GOSUB. As shown above, this means we can enter a subroutine repeatedly in the course of a program. N2: Subroutine Example The example program given below evaluates the circumference and area of a circle, and has a subroutine to round the results to two decimal places. The program works as follows: (1) Calculates the circumference (line 40), and makes this figure equal to variable Z (line 45), which is the variable the subroutine will round. (п) Enters subroutine (line 50). (ш) Corrects answer to 2 significant figures (subroutine lines 200 — 230), and returns with rounded value of Z to line 60, which: (iv) Prints out circumference (line 60). The same procedure is then repeated for the area, the subroutine being entered (called) again in line 90. Lines 200 to 23@ of the program are then executed again, but the RETURN statement this time returns control to line 100 (the next line after the last GOSUB statement). It is essential to have line 110, which prevents the subroutine being entered accidentally when the calculation is complete. 10 REM "CIRCLE" 20 PRINT "TYPE RADIUS" 30 INPUT R 40 LET C=2*PI*R 45 LET Z=C 50 GOSUB 200 60 PRINT "CIRCUMFERENCE IS ";2 70 LET A=PI*R**2 [ ^ Spectrum] 80 LET Z=A 90 GOSUB 200 170 100 PRINT "AREA IS ";Z 110 GOTO 3609 120 REM *MUST NOT ENTER A SUBROUTINE EXCEPT BY A GOSUB* 200 REM **SUBROUTINE TO CORRECT TO TWO DECIMAL PLACES** 210 LET Z=INT (100*(Z4.005)) 220 LET Z=Z/100 230 RETURN 240 **END OF SUBROUTINE** 300 REM **END OF PROGRAM** The second example is a program to evaluate the sum of the series 1 4 1/2! +1/3! +.. 41/10! to 6 decimal places. (The exclamation mark (!) means ‘factorial’. Factorial 5 (5!) is 5x 4x 3x2x 1, etc.). In this program there are two separate subroutines. The subroutines are both entered repeatedly. The first is to evaluate the factorial and the second corrects the answer to 6 decimal places. Although it is not essential to use subroutines in such a program it does improve the structure and make it considerably easier to follow the sequence of operations. 19 REM "FACTORS" 40 LET 5-й 50 FOR 2-1 TO 10 60 GOSUB 200 70 LET T=1/X 99 LET S=S+T 100 PRINT Z;" TH TERM IS ";T 118 NEXT Z 120 GOSUB 300 130 PRINT 140 PRINT "SUM OF SERIES ";V 150 GOTO 400 200 REM **SUBROUTINE FACTORIAL** 210 LET X=1 220 FOR N=1 'TO Z 230 LET X=X*N 240 NEXT N 250 RETURN 300 REM **SUBROUTINE 6 D.P. ** 310 LET V=INT (1E6*(S+5E-7) ) 320 LET V-V*1E-6 338 RETURN 400 REM **END** Results on screen: TH TERM IS 1 ҮН TERM IS 0.5 TH TERM IS @.16666667 TH TERM IS .041666666 TH TERM IS .083333333 ; - 0013888889 TH TERM IS .0001964127 TH TERM IS .000024801587 TH TERM IS 2. 7557319Е-6 TH TERM IS 2.7557319E-7 SUM OF SERIES 1.7182862 = оо - OY Ut i» Q N = < = "3 г = = ні о - 171 Trace the program through for the first two terms to ensure that you can follow the flow. N3: Nested Subroutines This technique is similar to nested loops in that a subroutine is entered from another subroutine. In the simple example given the program enters the first subroutine (line 300) and from within this calls up the second subroutine (line 320 calls up subroutine at line 400) which is completed and returns (line 420) to the first subroutine which is then completed. See the diagram below of the program flow. Hand trace this program to discover the result of running it. (N.B. This program is only used to illustrate nested subroutines and the calculation carried out clearly can be done more easily without their use. ) 10 REM “SUBROUTINE1" 20 LET M=5 30 GOSUB 300 40 PRINT M 58 GOTO 569 300 REM ****1ST SUBROUTINE**** 310 LET М=М+1 320 GOSUB 400 330 REM **RETURN TO MAIN PROGRAM** 340 RETURN 350 REM * k k k oo k k # k k k k k k k k k k k k Kk 400 REM ****2ND SUBROUTINE**** 410 LET M=M* (M+1) **2 [ # Spectrum] ‘20 RETURN 430 REM k k k k k k k k k k k k k k k k k k k k k k k 500 PRINT "END OF PROGRAM" The diagram illustrates the procedure in the above program for two nested subroutines. 30 GOSUB 300 40 50 сото 500 (7) 360 33$ sans 320 GOSUB 400 oo peas 34@ RETURN Е" (3) 35D .... (5) 49D .... 410 .... 420 RETURN 430 owes (1) Subroutine 1 is called at line 30. Enter first subroutine at line 300. (2) Start executing first subroutine. (3) Subroutine 2 is called at line 320. Enter second subroutine at line 400. (4) Execute second subroutine. (5) RETURN at line 420 returns program to line 330 (line following GOSUB call). (6) Continue execution of first subroutine. (7) | RETURN at line 340 returns program to line 40 (line following GOSUB call). (8) Statement to avoid entering subroutines accidentally. The second example is typical of a computer games program. The nested subroutine ensures that the computer’s move is printed out each time before the player makes his move. 10 REM "NESTSUB" 20 REM **PART OF GAMES PROG** 30 LET х-3 40 GOSUB 600 45 PRINT 50 PRINT "YOUR MOVE WAS ";M 60 PRINT "COMPUTERS MOVE ";X 70 STOP 600 REM **SUBROUTINE PLAYER** 610 GOSUB 700 620 PRINT "YOUR MOVE?" 630 INPUT M 640 RETURN 700 REM **SUBROUTINE COMPUTER** 710 PRINT "COMPUTERS MOVE ";X 720 RETURN Note that it would make no difference if the nested (called from a subroutine) subroutine were to start at a lower line number than the subroutine which called it. Subroutines are always discrete program modules, wherever they are located in a program. N4: Recursive Subroutines A recursive subroutine is a subroutine that calls itself. This facility 1s not available in some versions of BASIC used on other computers. For some purposes this can be a very useful program structure. From within a subroutine, a GOSUB instruction is used to transfer control so that the program re-enters the subroutine. The computer stores each GOSUB call, with the line number to RETURN to, just as if the GOSUB call had been made to a different subroutine. The RETURN instructions are executed in reverse sequence to the order in which the GOSUB instructions were encountered. The example program below evaluates the factorial. of any number N, input as an integer less than 30. First the program, then the explanation: 173 20 КЕМ 20 PRINT 30 INPUT М "RECSUE" "TYPE NUMBER<20" 40 IF М>20 THEN GOTO 200 S50 БОЦЕ 100 80 PRINT F 20 КЕМ 20 REM жЕ € € 93€ зен 3€ 9€ ж 1 THEN GOTO 140 100 REM *#+##SUBROLUT INE ++ 110 IF N <> 120 LET F=1 iso GOTO 180 140 LET NzN-1 150 GOZE 100 160 LET F=F*(N+1) 170 LET N=N+1 120 RETURN 135 REM **##*# END SUE жж 190 КЕМ 200 РЕІМТ “OBEY INSTRUCTIONS, РЕ ESS RUN AND NEWLINE/ENTER" 210 КЕМ **END#* To help us decipher the program flow, we can insert PRINT statements and add a counter, in order to code the GOSUB and RETURN instructions with a number to indicate the sequence in which the recursive calls are performed. Add the following lines to the program: 5 LET C=90 35 PRINT N 45 LET C=C+1 55 PRINT “RETURN TO MAIN РКОСКАМ” 145 LET C=C+1 146 PRINT “GOSUB CALL ”;С 147 PRINT “N=";N 155 PRINT''RETURN CALL “G 156 LET C=C-1 165 175 PRINT “Е=”;Е PRINT “N =’’:N (sets counter to count GOSUPB calls) (prints first value of N) (first GOSUB call from main program) (final RETURN executed) (increments counter each time GOSUB is used recursively) (prints each time GOSUB is used recursively) (value of N before each recursive GOSUB call) (prints each RETURN call as made, corresponding to the GOSUPB call of the same number) (decrements counter as each RETURN is executed) (value of F at each stage) (value of N at each stage) Then run the program for N = 3. The resulting ‘machine trace’ screen display 1s: 174 3 GOSUB CALL 2 N=2 GOSUB CALL 3 N=1 RETURN CALL 3 F=2 N=2 RETURN CALL 2 F=6 N23 RETURN TO MAIN PROGRAM 6 If we draw up a trace using the data from this display (as below), we will see that the GOSUB at line 150 is executed for each value of N from 1 to N. The RETURN calls are then made for each value from 1 to N, calculating F each time (line 160) and incrementing N (line 170), so that the value of factorial N is calculated as 1x2x3...x N. The flowchart of this program is quite simple, but the algorithm is not clear unless the sequence of GOSUB and RETURN calls is understood. The computer stores each GOSUB call in sequence in a portion of memory called the GOSUB stack, and each RETURN instruction removes one of these stored GOSUBSs, passing control to the line after the GOSUB call. Confusion is possible with recursive subroutines because the RETURNS are made to the same program line each time (line 160 in this case). “RECSUB”’ - Trace јот N = 3: 50 GOSUB(1) 60 100 N-3 N=? N=1 110 F 120 130 140 Nš2 Nš! 150 GOSUB(2) GOSUB(3) 160 E 170 180 R F = 1*9 F v 2%3 N=2 N =3 TURN(3) RETURN(2) RETURN(1) - (To main program) 175 Flowchart - ‘‘RECSUB”’ START ©) (2) F=F*(N+1) RETURNS TO LINE RETURN AFTER LAST GOSUB CALL. В) 176 Notice that line 130 passes control to the RETURN statement of line 180. Check for yourself that line 130 could be a RETURN instruction and the program would still run correctly. This is likely to result in a less visible flow in the program, however. The next program has a subroutine (starting at line 100) which calls itself in line 150. As for the previous program, insert suitable PRINT statements to print out the values of the variables and the number of GOSUB calls made. Hand trace the program for suitable integers, e.g. 15 and 25. The program evaluates the highest common factor of the two numbers input. Note that in this case there are no processing statements between the GOSUB call in line 150 and the RETURN instruction of line 160. The sequence of RETURNS will be executed by control going repeatedly to line 16@ (the line after the GOSUB call), which does the next RETURN, until the last stored GOSUB is encountered, which will pass control back to line 5@ of the main program. 5 REM “HCF" 10 PRINT “TYPE ‘TWO POSITIVE INTEGERS" 20 INPUT M 30 INPUT N 49 GOSUB 100 50 PRINT "ANSWER IS";P 68 GOTO 220 100 REM **SUBROUTINE** 110 LET P=N 120 LET N-M-N*INT (м/м) 130 LET M=P 140 IF М-й THEN GOTO 160 158 GOSUB 100 210 REM 220 REM **gND** N5: Computed Gosubs The line number N in a GOSUB N program instruction may be a computed expression: it is permissible to have any expression as the numeric value for a line number. We can make use of this in programs where we want to give the user some options of operations. Since we would write the program with these options as subroutines, a suitable choice of line numbers can allow us to present a menu to the user. Here are two (useless) examples to illustrate the principle: 1) 10 PRINT "MAIN PROGRAM" 20 PRINT "INPUT 1 OR 2" 30 INPUT X 40 GOSUB Х%100 50 PRINT "MAIN PROGRAM ENDS" 69 PRINT "NOW BACK TO MENU" 70 PRINT 80 GOTO 10 177 100 PRINT "FIRST SUBROUTINE" 110 RETURN 200 PRINT “SECOND SUBROUTINE" 210 RETURN 2) 10 REM *NESTED SUBS FOR MENU** 20 REM **INITIALISE MENU GOSUB** 30 LET MENU-14009 40 REM **MAIN PROGRAM** 50 PRINT "MAIN PROGRAM" 60 REM .... 70 PRINT "NOW TO MENU" 80 PRINT 90 GOSUB MENU 100 PRINT "MORE MAIN PROGRAM" 118 PRINT "MENU OR END PROGRAM?" 120 PRINT "INPUT M OR E" 130 INPUT NŠ 140 IF N$-2"M" THEN GOSUB MENU 150 GOTO 9999 1000 PRINT TAB 3;"MENU" 1010 PRINT ,,"1. OPTION 1",,"2. OPTION 2" 1020 PRINT "INPUT 1 OR 2" 1030 INPUT M 1040 GOSUB (M*1000)+100Q 1050 RETURN 1100 REM ****SUB l*****x* 1110 ВЕМ k k k k k k k k k k k k k * k 1120 PRINT "SUB 1 COMPLETED" 1130 PRINT 1140 RETURN 2100 REM ****SUB 2****** 2110 REM £ k k k k k k k k k k k k k k 2120 PRINT "SUB 2 COMPLETED" 2130 PRINT 2140 RETURN 9999 STOP Notice the use of a variable ("MENU") to hold the line number (1000) of the Menu subroutine (Lines 20 and 30). This technique can be useful as a mnemonic in longer programs, and can help the user identify which program module has been called. This technique can be combined with the use of INKEY$ to give an instantaneous jump to the required subroutine. The program waits for a key to be pressed and then jumps to the required subroutine. 10 PRINT "PRESS 1 FOR SUB 1"," PRESS 2 FOR SUB 2" 20 IF INKEYS="" 30 LET AS=INKEYS THEN GOTO 20 35 IF А5-"1" OR А5-"2" THEN СО TO 60 40 PRINT "KEYS 1 OR 2 ONLY PLE ASE" 50 GOTO 10 60 GOSUB VAL А5%100 70 PRINT "BACK TO MENU" 80 GOTO 18 178 PRINT "********k*kkkkkk" PRINT "SUBROUTINE ONE" PRINT "*********X**x" RETURN PRINT "soo x de e e e e x n PRINT "SUBROUTINE TWO" PRINT "s***k*kkkxkkx" RETURN Spectrum users should replace line 20 with 20 PAUSE Q N6: Subroutine Use: Example As an example of the use of subroutines, here is a guess-the-number game. The program has three subroutines, one to get the number (lines 150 — 190), one to check the guess (lines 210 — 300), and one for the success message (lines 350 — 410), which sets the marker MARK to tell the main program, which is the loop between lines 50 and 140, whether the number N (computer's number) is the same as G (the player's guess). This defines whether the success subroutine has been called as a result of the conditional test in line 110. 22 10 20 30 REM "GUESSNUM" LET MARK =0 LET TRIES=0 PRINT “GUESS MY NUMBER, "++, “NUMBER: IS BETWEEN 1 AND 99" (M9 е „ ts cC uy < ord -— — ЫҢ М. !. Же _ — “ІЛ -- ұл pe bh FS p I 63 3 Кә ка 0 CY oo ез» йу, — 1 — i+ p» pee de dex ooo C on oO ch 25 AND DISF <= 50 T HEN PRINT 95 "COLD" 260 IF DIFF>10 AND DIFF <= 25 T HEN PRINT у» "xWARIME" | 270 IF DIFF>4 AND DIFF <= 10 TH EN PRINT +," ж НОТ жж " 280 IF DIFE>O AND DIFF <= 4 THE N PRINT ss" жж #BCILING# жы" 290 RETURN 700 REM жж END CHECESZLUE xx 210 REM ххх хз ЖЖЖ ЖЕК 220 REM 240 REM 33 CC 30 KHER HEHE HEH GEO БЕМ жж зи Sup ++ SEQ REM хажы ғ HH ED 370 PRINT AT 9.95; "%%%%%7%%%7%%"; TAB 5: "$ SUCCESS %": TAB Si "$5 HEEE ESE" 380 PRINT АТ 10%5: "ІТ TOOK “ITR IES?" TRIES. “ 390 LET MARK =1 400 RETJEN 410 REM жж END SUMCESS Sie жж 420 REN X3X33X3 939 0 HE EK EE Y 430 СЕМ 470 REM жж ЖЖЖ 490 REM жж END/RESUN MOD xx 495 БЕМ 3*3 9 X 3 X 3 30 Ж Жы 200 PRINT ,$4"ANUTHE SO? INPUT Y OR N" SiO INFUT A$ CL 930 IF A$z"Y" THEN GOTO АО 940 PRINT +. "Ok. BYE" wool STOP Se REM xx xx END хх жж The structure of the program is thus: Module 1: 1. Initialise success marker MARK and variable to store number of guesses made (TRIES) 2. Print Instructions 3. Call GET NUMBER Subroutine Module 2 (Main program loop): 1. Increment TRIES 2. Input guess 3. Call CHECK Subroutine 4. Check if Guess equals Number. If it is, then call SUCCESS Subroutine 5. Check marker. If Success subroutine has been called (MARK = 1), then GOTO END/RERUN module 6. Loop back to Input guess again (1) 180 Module 3 (GET NUMBER Subroutine): 1. Define random number 1-99 as number N 2. Return Module 4 (CHECK Subroutine): 1. Set variable DIFF equal to ABS difference of guess and number 2. Check value of DIFF, print appropriate message 3. Return Module 5 (SUCCESS Subroutine): 1. Print success message, number of guesses made 2. Set MARK equal to 1 3. Return Module 6 (END/RERUN module): 1. Print prompt for input 2. Input response to Another go? (A$) 3. If replay required (A$ = ‘‘Y’’) then GOTO Module 1,3 4. If A$ not “Ү” then print end message 5. Stop Notice that (although this is a program that has been modularised rather artificially to demonstrate the principles in a short program) the program consists of an introductory section, then a main program loop with both conditional and unconditional calls to subroutines, within a short main program loop. This makes the structure of the program clear, and minimises the use of GOTO statements, which would be required in profusion if the program were written in a linear, rather than modular fashion. It is perfectly possible to write the program in this linear manner, but the structure will not be as visible. You should also note that the END/RERUN module is not a subroutine, but uses GOTO to pass control to this section from the main program, with a conditional GOTO to pass control back to the main program if required. Conditional GOTOs аге preferable program structures to unconditional GOTOSs, and whilst the END module could be a subroutine, RETURNing to the main program loop, further conditions would need to be inserted to pass control to Module 1 for a new number to be defined. The subroutine would also need to be exited by а GOTO for the program to stop. There is another solution, however, involving a nested subroutine, which we will set as an exercise. Exercises 1 Rewrite /GUESSNUM"' with the END/RERUN module as a subroutine. The procedure should be as follows: END/RERUN SUB i. Prompt for player input, and get response, as before. 181 п. If RERUN not required, bypass 3 апа 4 below, by a GO TO the RETURN line. ш. GOSUB to GETNUMBER subroutine. This is a nested subroutine. The new value of N will be set by this operation. iv. Re-initialise TRIES as 0 and MARK as 0. v. Return. The main program loop is then returned to. The main program must then test whether it is to exit (rerun not required) or continue (new game started). We could set another marker to test this, but in effect we have done this by re-setting MARK ifa rerun is required. Rewrite the main program loop, so that on return from the END/RERUN subroutine, the program loops back only if MARK = 0. If MARK = 1 then the program will not loop back and you can either insert a GOTO to bypass all the subroutines to an end program procedure, or STOP the program before the subroutines. Insert an additional subroutine which prints 1;‘‘ST’’,2; “ND”,3;*°* RD”, and then “ТН” for other numbers into the “FACTORS” program (Unit N2). Write a program which determines how many rolls of a die are required to produce a total score greater than 100. Use subroutines to produce the random numbers for the die rolls and to print out the results. Let the computer choose a four digit number with no two digits alike. You try to guess the number chosen. The computer indicates H (too high), L (too low) or R (right) for each digit in turn and determines how many guesses are required to get the correct number. Use subroutines to create the number, input the operator's guess and give the response to each guess. 182 PART THREE ADVANCED BASIC PROGRAMMING ТАРЫ s ДАЧ ОЛА мМАЯООЯЯ MEAN LOW ATTO А SECTION O: PROGRAMMING METHODS II O1: Résumé Before we enter the arena of advanced BASIC programming let us recap on what we have examined and accomplished so far. The method to design the solution or algorithm to a computational problem using ‘top down’ analysis has been explained. We have seen how to break our problem up into sub-problems which form our program modules (using tree diagrams). We know how to describe the algorithm in concise English sentences that we call pseudocode and how to determine and illustrate the flow of control in the problem solution by drawing a flowchart. When designing our solution we recognise the need to use the fundamental programming tools of: (1) decision making (п) branching as a result of decisions (iii) direct transfer from one point in the algorithm to another (iv) repetition These control structures, as they are called, which are present in all computer languages, have been discussed in some depth, together with other important BASIC language fundamentals. The techniques of: (1) decision making (п) numeric processing (iii) character handling with strings (iv) looping through counting and condition testing (v) handling of output by printing and plotting and the realisation of modular techniques in programming by using subroutines have all been covered. WHAT'S NEXT? We must now consider the second phase of the programming method - producing the program itself. It 1s important to do so at this stage in the book, so that our programming tool kit is complete enough to investigate and use the more sophisticated information handling facilities to be introduced later in this section: (1) logical operations on data (1) character codes (uni) moving graphics (iv) graph plotting (v) constructing and searching lists and data arrays (vi) how to sort information into order Once these skills have been mastered our complete programming expertise can then be applied to real applications. Let's now see in this section of the text how to code our algorithms into BASIC language programs, and then debug, test and document them. 185 Further important design rules will be given, and finally a summary of our complete programming method will be provided with a flowchart and worked example. O2: Producing the Program We now consider the method by which a well designed, tested and fully documented program is produced. Given our algorithm - which we have written out in steps in a description we call pseudocode — together with our flowchart — which shows how the steps of the solution are combined in sequence for the computer to solve the problem - we must now: 1. CODE THE ALGORITHM IN SINCLAIR BASIC 2. DEBUG AND TEST THE PROGRAM 3. DOCUMENT THE PROGRAM O3: Coding and Design CODE ON A ONE TO ONE BASIS If the description of the algorithm is correct then coding on an almost one to one basis from statements in the pseudocode or the flowchart is possible. If you cannot code from the flowchart or pseudocode then further refinement of the algorithm is necessary. Pseudocode descriptions in formal mode of the BASIC language control structures for decisions and loops are given later in this section. You will notice that the description itself is indented and concise, with the terms almost the same as BASIC statements. This is not unusual as BASIC was designed to do this very thing and 1s English-like in its syntax. To be able to code at all you must of course: KNOW THE BASIC LANGUAGE AND ITS RULES Hopefully it is the right language for the job. On the ZX81 and Spectrum you don't have much choice! Actually it is a question of ease of programming specific applications that generates different languages. Most things can be done in BASIC, although perhaps not efficiently or elegantly. It is often useful to identify the kind of processing that will be required. When designing the algorithm consider whether the problem is a scientific or a business application, whether extensive calculations will be performed or large amounts of list processing done, whether the data is extensively numeric or string and whether the program will be interactive with much user dialogue. When coding, avoid spelling and formatting mistakes. Sinclair BASIC is powerful in that it is one of the few available single keystroke 186 BASICs, hence you cannot make spelling mistakes on instructions or commands because the whole instruction is keyed in at once. However, mistakes can still be made when assigning variable names and in PRINT and REM statements. DEFINE AND CONTAIN EACH MODULE WITH REM STATEMENTS For example: 100 REM * SORT MODULE * 200 REM * THIS MODULE SORTS STRINGS * 500 REM * END SORT * TERMINATE YOUR PROGRAM PROPERLY You may have noticed that Sinclair BASIC does not need a special end-of-program statement. We can, however, put one in using a REM statement. For example: 500 REM * END OF PROGRAM * Тһе 7Х81 and Spectrum do not process but only note REM statements. When the above line runs, the program will finish elegantly with a 0/500 message. We can also stop a program with the STOP statement. Main modules should finish like this with subroutines programmed at higher line numbers terminated with a REM * END * statement. When terminated with STOP a message 9/line number (a 9 Stop (Line number): 1 statement on Spectrum) will be given. REM * NAME OF PROG * 10 REM * MAIN MODULE * 20 GOSUB 500 30 STOP 40 REM * END MAIN * 500 REM * SUBROUTINE * 600 RETURN 700 REM * END SUBROUTINE * 800 REM * END OF PROGRAM * We could also use a GOTO 800 at line 30 to terminate execution on the last program line. ALWAYS CODE ACCORDING TO THE LOGICAL ORDER OF PROCESSING This is usually ensured if you code from a flowchart, with your 187 flowchart structured into modules, i.e. flowchart groups for the modules in the program. Take care with the control structures and avoid unnecessary branching, especially with GOTO instructions. Try to make your programs both readable and efficient — but first make them readable! USER FRIENDLY PROGRAMS Design your programs with the user in mind - and that includes you! Directions to users should be concise and as few as is necessary, both in the program and in the user guide if your program is large enough to merit one. Where the user needs a number of instructions to operate the program then these can be built into an optional ‘help’ module or subroutine. 100 REM * USER INSTRUCTION * 110 REM * DIRECTS USER TO HELP SUBROUTINE * 120 PRINT “ FOR INSTRUCTIONS TYPE HELP OTHERWISE TYPE C " 130 INPUT A$ 140 IF A$ - *HELP''THEN GOSUB 1000 150 REM * END USER INST * 1000 REM * HELP SUBROUTINE * 1200 RETURN 1210 REM * END HELP * Users usually require to know: ~ how to run the program — what form of input data is required — what output is produced Your program should check on the range and type of input data. If the input data is out of range or incorrect the program should not stop with an error, but continue with a message to input correct data. After you have designed a program to do a specific task it may be worthwhile to change it to be as general as possible — i.e. do several similar tasks. As you become more skilled and confident in programming you will be able to generalise and write a subroutine that enables users to select options from a menu. This is exactly similar to the exercise you have seen in multiple decision structures. See the "CASSFILE'' program in Section V, for a ‘‘menu-driven’’ program. More “‘user-friendly’’ tips are given in the section on documentation, and some useful routines in Unit V2. 188 DESIGNING PROGRAM LAYOUT You must make your program readable. The program design will be modular and contain specific identifiable segments, subroutines and modules. These should be labelled in the design of the algorithm and transferred in the coding process. (1) EACH MODULE SHOULD BE TITLED AND LABELLED TO INDICATE ITS FUNCTION. FOR EXAMPLE: 10 REM “AVERAGE” 20 REM * PROGRAM AVERAGES ANY NUMBERS INPUT * 3 REM * 40 КЕМ * USER ROUTINE * 50 REM * CHOICE OF NUMBERS INPUT * 60 PRINT “HOW MANY NUMBERS DO YOU WISH TO АУЕКАСЕ” 70 INPUT N 80 DIM A(N) 9) REM * INPUT ROUTINE * 100 REM * NUMBERS INPUT TO ARRAY * 110 PRINT “INPUT NUMBERS" 120 FORI=1TON 130 INPUT A(I) 140 NEXT I 150 REM 160 REM * PROCESSING ROUTINE * 170 REM * COMPUTES AVERAGE * 180 LET SUM-0 199 FORJ=1TON 200 LET SUM = SUM +A(J) 210 NEXT J 220 LET AVERAGE - SUM/N 230 REM 249 REM * OUTPUT ROUTINE * 250 PRINT “THE AVERAGE OF" 260 FOR K=1 TON 270 PRINT A(K); ”’; 280 NEXT K 290 PRINT “IS ”; AVERAGE 300 REM 310 REM * END AVERAGE * (2) DESIGN YOUR PROGRAM SO THAT RELATED STATEMENTS ARE TOGETHER For example, input — processing — output statements: () All input statements will be at the beginning of a simple sequential program, processing in the middle, and output normally at the end. 189 (3) (4) (9) (üu) For a modular program, input, processing and output routines will be separate modules or groups of statements within a single module. (ш) Subroutine modules will usually be placed separately at the end of a program. INSERT REM STATEMENTS BETWEEN PROGRAM MODULES AS SEPARATORS Program modules are then easily identified. Use blank REM lines or lines of asterisks. PLAN YOUR PROGRAM LAYOUT BEFORE CODING The printed listing of your program is important. Choose a maximum line width. Break longer lines into shorter ones in REM statements by using spaces. Compensate for overrun. For example: 10 REM * AAAAA AAAAA AAAAA * You will not be able to do this with other BASIC statement lines. YOUR LAYOUT SHOULD TRY TO REFLECT THE MODULAR STRUCTURE OF YOUR PROGRAM 190 Indented statements are not possible on the ZX81 or Spectrum, unfortunately! DESIGNING PROGRAM OUTPUT For the user the output is the most important part of the program. Take time planning it. The output instructions in Sinclair BASIC are: PRINT, PRINT AT, PLOT, LPRINT, COPY, TAB, plus graphics commands. () RESULTS SHOULD BE OUTPUT WITH RELATED ITEAL Label all your numerical output: єн. 1974 £5678.65 instead of 1974 5678.65 e.g. AVERAGE AGE OF BOYS IS 15 YRS 3 MONTHS rather than 15 3 (i) DISPLAY LARGE AMOUNTS OF OUTPUT AS A TABLE, HISTOGRAM OR GRAPH, AND GIVE TITLES. For example: TABLE 1: NET INCOME FOR B. JONES FOR YEARS 1978-80 Box your tables if possible. The user should not have to look up the program listing to see what the numbers in the output mean. au) DESIGN YOUR OUTPUT TO BE EASY TO READ Plan it to be attractive to any user of your program and, of course, yourself. Graphics is a powerful tool for this. (iv) ALIGN, SPACE AND JUSTIFY THE OUTPUT Plan your output with reference to the screen size and divisions. For tables — align information central to the heading align signs right justify numbers left justify characters. (There are routines in the text for doing this). For example: 876-340 JIM SMITH 27-210 HUNG FO 453-003 SARAH JAY 1-025 DRACULA NUMBERS 15.003 815.231 - 4.000 – 100.100 Fill in with zeros to get decimal placing correct. (v) USE SPACE CAREFULLY Sinclair computers use expensive printer paper! Print output horizontally wherever possible. For example: TABLE OF POWERS OF 2 2 4 8 16 32 etc should be: TABLE OF POWERS OF 2 2 £ 8 16 32 64 128 256 512 1024 (vi) DO МОТ OVERDO EXPLANATIONS Be succinct! (уп) MAKE YOUR ABBREVIATIONS CLEAR x = 25 NDTC =25 NUMBER OF DAYS TO CHRISTMAS = 25 (vii) DISPLAY INPUT DATA AS AN OPTION Allow checking of input data before processing. Make your program check for incorrect or bad input data. MODULAR DESIGN We break problems down into sequences of steps to produce programs in which different kinds of activities are separated out. These distinctive program modules are our SUBROUTINES or SUB- PROGRAMS. Each module has its own name and address, but in BASIC we usually refer to program modules by address only, as with: GOTO 100 and GOSUB 3300 where the address is the line number of the first statement in the module. We can address sub-programs or modules by name by assigning the name and address of the module at the start of the program. For example: 10 REM * ASSIGN MODULE NAMES * 20 LET INPUT DATA = 1000 30 LET PROCESSING = 2000 192 40 LET OUTPUT DATA = 3000 59 REM * END MODULE ASSIGN * 60 REM 70 REM * MAIN * 80 GOTO INPUT DATA 90 GOSUB PROCESSING 100 GOTO OUTPUT DATA 110 STOP 1000 REM * INPUT DATA MOD * 1500 GOTO 90 1600 REM * END INPUT * 2000 REM * PROCESSING SUBROUTINE * 2500 RETURN 2600 REM * END PROCESSING * 3000 REM * OUTPUT DATA MOD * 3500 GOTO 110 3600 REM * END OUTPUT MOD * 4000 REM * END PROG.* There are good reasons for modular design and the use of subroutines and sub-program modules. The logic of the program, i.e. its flow, is easier to follow. The clarity of the structure of the main program is improved whilst program design is proceeding by referring to the number or name of the module initially, instead of starting to write out the code of the module at that point. The module can be coded as a separate entity. Independent testing of modules is possible, but care must be taken that all variables have been declared and have their correct values at the start of the module. Debugging 1s simpler with this approach, since the module is isolated. You can leave the coding of a module until a later stage, but you must know what it will do when coded. If a module has to be used several times in a program from different places it need only be written once and called (into action) from these points by reference to its line number or name. 193 Program modules can be designed to run sequentially: START MODULE 1 INPUT MODULE 2 PROCESSING MODULE 3 OUTPUT STOP This structure is convenient for simple programs. However, programs can be structured in terms of subroutines and sub-programs being called from a short and simple main program module. START MAIN a MODULE MODULE 2 MODULE 3 194 This structure is convenient for longer, more complicated, programs with many modules and nestings. Subroutines automatically return to the next line in the main program through the RETURN statement. Other modules are called by GOTO (line number) and return by GOTO (line number) instructions. GOTO MUST BE USED WITH THOUGHT AND CARE AND NOT EXCESSIVELY. Use a GOSUB unless a return to a different point in the main module is needed or a multiple return is possible as a result of a decision to be made within the module. Nested modules can be treated as other modules and called from within the subroutine or sub-program, by GOSUB and GOTO instructions. Nested loops must be contained within the same module, however. CONTROL STRUCTURES IN SINCLAIR BASIC (1) Each control structure is a program module. (2) A formal pseudocode description of each structure is given of the general form of the control structure. (3) A flowchart description is given of the general form. (4) The BASIC version is given of the general form. (5) A simple example illustrates the BASIC form of the control structure. (6) Structures will be written in indented form in the pseudocode version for clarity. You cannot indent in Sinclair BASIC program listings. REM statements must be used to show the start and stop lines for program modules. (7) P is a processing operation. It can be a single instruction, a statement or a group of statements. (8) In the formal pseudocode each structure will commence with the title module (abbreviated to mod), and end with the statement endmodule (abbreviated to endmod). (9 In BASIC cach structure will be bounded by REM*STARTMOD* and REM*ENDMOD* statements. (10) Flowcharts will be bounded by START and STOP symbols. The structures summarised are: A) Decision Structures (1) Single decision IF-T HEN structure (п) Double decision IF-T'HEN-else structure (ш) Multiple decision Case structure 195 B) Loop Structures (i) repeat-forever loop structure (ii) repeat-until structure (iu) while-do structure (iv) FOR-NEXT structure The names of the structures are implemented as actual programming language structures in other languages and some forms of BASIC. The FOR-NEXT structure is a special form of the while-do loop, given a specific implementation in BASIC. A. DECISION STRUCTURES () SINGLE DECISION: The IF-THEN structure Meaning: IF (condition is true) THEN (do something) Pseudocode Flowchart mod if (condition) then P endif endmod BASIC 10 REM*START MOD* 20 IF (COND) THEN P 30 REM* ENDMOD* Example Input a number and if it is positive, print it. Pseudocode BASIC mod 10 REM*START MOD* input A 20 INPUT A If A > Q 30 IF A>@ THEN PRINT A then print A 40 REM*END MOD* endif endmod 196 (i) DOUBLE DECISION: The IF-THEN-else structure Meaning: IF (condition is true) THEN (do something) otherwise (if condition is false) do something else. Pseudocode Flowchart START mod if (cond) then P1 else P2 endif endmod BASIC 10 REM*START MOD* 20 IF (COND) THEN GOTO 50 30 (FALSE TASK P2) 40 GO TO 60 50 (TRUE TASK P1) 60 REM*ENDMOD* To perform the true task (P1 in the pseudocode) first, the BASIC implementation of the structure would test the complement of the condition, so that in the program below, for example, A>B would be replaced by AB 30 INPUT B then print A 40 IF A» B THEN GOTO 70 else print B 50 PRINT B endif 60 GOTO 80 endmod 70 PRINT A 80 REM*ENDMOD* (ш) MULTIPLE DECISION STRUCTURE: The case structure With this structure we want the program to select and perform one of several alternative tasks. The conditions in this case structure are sequential, not nested and mutually exclusive. Pseudocode Flowchart mod case if (condition 1 is true) then P1 if (condition 2 is true) then P2 if (condition 3 is true) then P3 end case endmod 198 BASIC 10 REM*STARTMOD* 20 IF Cl THEN P1 30 IF C2 THEN P2 40 IF C3 THEN P3 320 REM*ENDMOD* Example Test whether a number input is positive, zero, or negative, and print the result. Pseudocode Flowchart mod input A case PRINT if A<0 NEGATIVE then print “МЕСАТІУЕ” If А = 0 then print “ZERO” if А>0 then print “POSITIVE” endcase endmod PRINT d PRINT POSITIVE 199 BASIC 14 REM*STARTMOD* 20 INPUT A 30 ЕА < 0 THEN PRINT “NEGATIVE” 40 IF A-0 THEN PRINT “ZERO” 5) IF A>@ THEN PRINT “POSITIVE” 60 REM*ENDMOD* Alternatively, we can use conditional and unconditional GOTO statements to implement this structure. This would be appropriate if the processing section of a program after the decision were several statements long, rather than the single instruction available on the ZX81. Spectrum users can add more instructions on the same line. They should be restrained in using this facility. 10 REM*STARTMOD* 20 INPUT A 30 IF A< 0 THEN GOTO 60 40 IF A-0 THEN GOTO 80 50 IF A>@ THEN GOTO 100 60 PRINT “NEGATIVE” 70 GOTO 110 80 PRINT “ZERO” 90 GOTO 110 100 PRINT “РОБІТІУЕ” 110 REM*ENDMOD* В. LOOP STRUCTURES (1) The repeat — forever loop Meaning: None. The only conceivable result is the program halting with an arithmetic overflow report. Pseudocode Flowchart BASIC (такт) 10 REM*STARTMOD* START 20 P 30 GOTO 20 mod 40 REM*ENDMOD* repeat P forever endmod 200 (i) This structure is for demonstration only. Avoid using it in programs! It can sometimes occur in error. Use BREAK if you suspect your program has entered such a loop (because nothing happens). The repeat — until loop Meaning: Repeat processing until a condition is true. These structures loop until a specific termination condition is met, for example until a counter reaches a certain value or until a dummy or sentinel value 1s input. The important characteristic of this loop structure is that the repeat test (or exit test) is at the bottom of the loop, after the processing ‘body’. The program lines making up the body of the loop (P) will be executed at least once. The repeat condition can use any conditional operator or its complement (reverse). e.g. equals 4—0 not equal - <> Use of the complement often leads to a more elegant program. Pseudocode Flowchart mod repeat P until (condition is true) endmod BASIC 10 REM*STARTMOD* 20 P 30 IF (COND) THEN GOTO 50 40 GOTO 20 50 REM*ENDMOD* 201 BASIC using complement 10 REM*STARTMOD* 20 P 30 IF (COMP COND) THEN GOTO 20 40 REM*ENDMOD* Exit requires no specific instruction. Example Input and print strings until the sentinel value “LAST” is input. Pseudocode Flowchart START mod repeat INPUT Ag input A$ print A$ until A$ = LAST endmod PRINT Ag Ag-LAST ? BASIC 10 REM*STARTMOD* 20 INPUT A$ 30 PRINT A$ 40 IF A$=‘‘LAST’’ THEN GOTO 60 50 GOTO 20 60 REM*ENDMOD* 202 Complement Version 10 REM*STARTMOD* 20 INPUT A$ 30 PRINT A$ 40 IF A$<>‘‘LAST’’? THEN GOTO 20 50 REM *ENDMOD* (ш) While — do structure Meaning: While a condition holds (TRUE) keep repeating the process until the condition is broken (FALSE). The condition can be, for example, that a loop-counter variable value is not equal to its final value (IF N<10 THEN..). The process will then repeat until it is. The condition may also be set so that a sentinel value has not occurred (IF N<>6 THEN). These conditions are set so that the true pathway is the process task, and the false is the exit. The While — do loop is characterised by having the repeat test carried out prior to the body of the loop (i.e. at the top). No processing will happen if the repeat test is false at the first encounter, i.e. the body of the loop is never entered. Pseudocode Flowchart START mod while (condition is true) do P endwhile endmod BASIC 10 REM*STARTMOD* 20 IF (COND) THEN GOTO 40 30 GOTO 60 40 P 50 GOTO 20 60 REM*ENDMOD* 203 (iv) Using the complement of the repeat condition gives a neater program. Complement Version 10 REM*STARTMOD* 20 IF (COND) THEN GOTO 50 P 40 GOTO 20 50 REM*ENDMOD* Example While the value of the square of consecutive integers is less than 100, print them on the screen. Pseudocode BASIC (complement) mod 10 REM*STARTMOD* п = 1 20 LETN=1 while п*п< = 100 30 IF N*N>100 THEN do print n*n GOTO 60 n=n+1 40 PRINT N*N 45 LET N=N+1 end while 50 GOTO 30 endmod 60 REM*ENDMOD* FOR - NEXT Loops FOR - NEXT loops are a special BASIC structure for repeating a process a stated number of times. They are in fact While — do loops and have the repeat test at the top of the loop. Example Print the values of the first ten integers. Pseudocode BASIC mod 10 REM*STARTMOD* n= 1 20 FOR N=1 TO 10 While n < = 10 30 PRINT N do print n 40 NEXT N п=п+1 50 REM*ENDMOD* епа while епатоа FOR - NEXT loops have their own special flowchart symbol, because they are used so extensively in BASIC: 204 Ordinar Special This is a condensed version. It groups together the FOR — NEXT — STEP instruction elements, which the standard form separates. This illustrates both a While do and a FOR- NEXT structure. O4: Program Development Program Development involves the activities of DEBUGGING your program of errors, TESTING to see if it behaves as specified and gives the desired results, and DOCUMENTATION which tells users how to run the program. DEBUGGING The Sinclair machines have good editing facilities and error messages. Those on the Spectrum have brief statements of the error type, those on the ZX81 have just a number or letter. Although it is inefficient to correct errors one at a time (because there is seldom only a single error since programming mistakes tend to compound one another), error messages on the machine are produced singly, since an error stops the computer from running. Thus we must deal with the errors as they occur in the program sequence. You may notice a number of errors on carefully looking through the listing. Any you spot should be edited out at once. GET TO KNOW YOUR COMPUTER ERROR CODES This will happen automatically in time (as you make mistakes!), but it is worthwhile studying the codes. They define the ways in which 'run- time' errors occur, and an understanding of them will help you avoid bugs. 205 EXIT Keep a note of mistakes you have made and how you corrected them. This will be valuable for future reference. This should become an automatic part of your personal documentation. Keep a copy of old program listings. Record the errors you have made, the corrections you tried but which did not work, and what you learned in developing the program. Trace the impact of any error through the program. SYNTAX ERRORS These are caused by BASIC statements you key in which do not obey the precise language rules (syntax rules) of Sinclair BASIC. The syntax errors are detected by the LINE INTERPRETER which automatically checks each line you key in when you press the NEWLINE (ENTER) key. If there is an error the interpreter will place the SYNTAX ERROR cursor just before the first error it detects on the line. This may be at the end of the line if the interpreter finds that something else should have been placed there. To correct this type of error you must compare the syntax you have written with the rules of BASIC. Typing instructions incorrectly cannot occur on the Sinclair computers as the BASIC 15 single key-stroke. In other BASICs you must type P,R,I,N,T, for PRINT. Instructions in general are automatically placed in the correct order along a line (i.e. the order of line number - instruction — operand), since they are taken care of by the mode controller which sets the cursors in the correct sequence. Errors which can occur are: 1 Omission of line number Line number too large (29999) Line number negative Line number non-integer Omission of delimiters: brackets (must be paired) commas semicolons quotes colons (on the Spectrum) 6 Typing in of improper variable names 7 Incorrect logical expressions There can be more than one error per line. The S-cursor will re-appear in the line when you try to enter it into memory. The line edit facility is comprehensive and easy to use on the ZX81 and Spectrum. You must correct your mistakes, and keep trying to ‘compile’ the line into correct BASIC syntax (to be entered into memory). When successful, the program line will appear at the top of the screen. The syntax error check ensures no nonsense lines (from the computer's point of view) are entered. It cannot help you in coding correct sequences of program lines, or prevent logical errors. сл ны оо ho 206 PROGRAM LOGIC ERRORS These are the effect of bad logical design of the program. They can be avoided if care is taken in the design and coding of the program. Ifa program produces incorrect results then there is an error in the flow of logic in the program. This may only occur with certain values of data. If each program section or module has been tested independently then the linking of the modules is incorrect. We can test program sections as follows: 1) Insert a temporary breakpoint into the program, at the appropriate point. 2) Print out values of intermediate results, to the screen or printer. 3) It is most important to print out the values of variables used in making a decision and those used in loops, either counter loops or FOR - NEXT loops. 4) Go back to the pseudocode or flowchart and modify the steps which are in error. ‘Walk through’ the algorithm, using a flowchart, to check the step sequence, and hand trace the program with selected values of data and/or variables. Be careful! Often changes in one part of the algorithm cause changes in the others. It is no use solving one problem if it causes another! 3) Change the documentation if necessary. Note down the changes you have made, or lines you have deleted. Keep program listings. 6) Re-test the complete program, using a variety of data. Each testing statement in a complex program should be headed by a remark statement. 1000 REM - DEBUG — (Testing Statements) - REM - END DEBUG These temporary REM statements are later deleted by keying in their line numbers, as are the testing statements. It is very easy to leave in test instructions unless they are marked. INSERTING BREAK POINTS We can stop a program at any point and obtain the values of variables, expressions, etc. to test calculations or check for errors. We do this by 207 Inserting a group of statements which will output the values we want and then stop the program. qM < ADD TEST OUTPUT OF VARIABLES МШ < INSERT STOP STATEMENT CONT will restart the program. Individual modules or sections of program can be tested this way. We do, of course, have to RUN the program from the required module line number. Care should be taken when this is done that variables needed in the module have been declared properly and that the values of parameters passed to the module are as required. Remember that you can INPUT the values of variables directly if necessary, using the command mode, and using LET statements: LET X(2) = 20, etc. The value of any variable at the point the program crashed can also be obtained by keying a statement without the line number, and again using the computer in command mode: PRINT A$ LPRINT X(3) The commands RUN N (where N is the line number we wish to run the program from) and GOTO N enable us to run the program starting at any point. Using GOTO N does not negate the initialisation of variables that occurs 2 the program has already run. For example, if we input: 10 LET A=1 20 LET B = 2 39 PRINT A,B and then key in GOTO 30, we get the error report ‘2/30’ (ZX81) or ‘2 Variable not found 30:1' (Spectrum) meaning an undefined variable was found. If we RUN the program, we can then use GOTO 30, and the program signals successful completion. RUN-TIME ERRORS These are a result of programmer carelessness and do not prevent the interpreter from translating the program. They make the program crash when you attempt to run it, that is they prevent the program from running to completion. Common run-time errors are: 1) undeclared or unidentified variables 2) arithmetic overflow 3) lack of data for processing 208 4) failure to complete loop increment and subroutine section statements 5) subscript out of range 6) memory full 7) screen display file full 8) integer out of range As we have seen, run-time errors cause diagnostic system messages to be printed. ‘These appear at the bottom of the screen and are called: ERROR CODES These errors can then be traced through the type of error given by the code and the line number at which the program stopped. ERROR CODES Error codes or Report codes are presented on the screen when a program stops for any reason, either as a result of successful completion (no more program lines), an instruction or command (STOP, BREAK), or a run-time error. On the ZX81 the codes have the form E/N, where E is the code for the type of error and N is the line number where the program was stopped (STOP or BREAK), or where an error occurred. N is @ fora direct command. This is an example of an error code on the ZX81 which is printed on the screen when an arithmetic overflow (number larger than about 10% generated) occurs in line 60 of the program: 6/60 The Spectrum gives an extended error report code, with a brief statement in the form: E Statement N:S where E is the report code, the statement is the reason for stopping (with BREAK or STOP or program completion) or type of error. N is the line number, but since the Spectrum can have multiple line statements, the S number indicates which statement on the line the report code refers to. We are not using multiple line statements in this text, so S will always be 1, meaning the first (and only) statement on the line, unless after the THEN in an IF... THEN statement, which 15 treated, like a colon, as a statement separator. The Spectrum's version of the example given above (the ZX81’s arithmetic overflow error code) is: 6 Number too big 60:1 Report codes are crucial aids to debugging programs. Without them we would know only that we had an error, but not where it occurred or what type of error it was. The error reports indicate both of these items of information. It is important to understand that the cause of an error may come earlier in a program than the line where the program stopped. For example, a code 2 error (variable not found), occurring in line 100 of a program might be caused by a mis-spelt variable name in line 100 (not 209 the same as the variable you meant it to be — putting GUES when you meant GUESS, for example). It could also be the result of not having assigned the variable earlier in the program. If the error causing the program to halt is not apparent from the line given in the error report, the program flow must be traced backwards to find the prior cause. In some cases this can be extremely difficult to track down - for example, where a numeric value wrongly defined or generated by the program causes another expression to cause an arithmetic overflow. Tracing techniques must be used. Lists of Error codes and their meanings for the ZX81 and Spectrum are given in Appendix II. TESTING AND VERIFICATION Verify that your program works by testing it with Test Data Testing comes after debugging a program. Its purpose is to ensure that the program is logically correct, produces correct answers and meets the specification of its purpose. 1 First test each module separately Each procedure and subroutine should be treated as if it were a separate program. Test for (i) good data - the expected type and range of inputs. (1) bad data — out-of-range and incorrect type inputs. Try to ensure each procedure ‘fails softly’. For bad data (particularly in any data entry module) following each input a check routine or procedure should be used to give an error message if range is incorrect or check type of input and correct syntax. This is best done with strings, which are more flexibly handled. See Unit V which deals with input checks at length. 2 Combine the modules and test the complete program If there is a logical error (1.e. program does not produce the intended results) insert additional test statements which will: (i) Output intermediate results. (11) Output values of variables at each stage. (iii) Output results of expressions at each stage. (iv) Output values of the loop counter at each pass. (v) Output results of array manipulation after each operation. (vi) Output values of parameters before and after subroutines entry and return. 3 Handle exceptions (1) Test all data in the program. (11) Screen all data. (111) Process only good data. (iv) Output bad data saying why it was bad. 210 4 Let your program stop elegantly (1) When there is no data input or data available, the program should tell you so. (1) Sinclair BASIC programs are interactive. The user сап control program continuation with: 910 PRINT “PROCESSING ENDED - MORE DATA? ANSWER YES OR МО” 920 INPUT A$ 930 IF A$ = “YES” THEN GOTO 100 940 PRINT “GOODBYE” 950 STOP 960 REM PROGRAM END 5 Rewrite the program until you are satisfied with it Remember the program should be - structured — easy to read — easy to understand — handle exceptions — be as efficient as possible — documented and it must solve the problem as specified! 6 Put clarity before efficiency To be good a program algorithm does not have to be clever, difficult to understand or run super-fast. If you do not understand how the algorithm works do not use it — rewrite and re-design or use another method. Programs will work correctly if the rules of the language are obeyed, and the program will work to specification if the algorithm 1s properly designed. DOCUMENTATION ANNOTATE AND DOCUMENT YOUR PROGRAM AND CREATE A READABLE PROGRAM 1 Write an explanation for each program module or segment. At the beginning of each segment provide suitable comments which explain: (1) the purpose of the algorithm (2) the variables and their significance (the values they store) (3) the results expected. 2 Use comments only where necessary: (1) don't comment each program line (2) don't explain the obvious (3) at the beginning of the program provide a block of 211 10 comments that explain the program at each module and provide a comment which explains what the module does in relation to the program. Clear comments should appear separated from program code. The clearest comments are framed. For example 19 REM * * * * * * * * 20 REM * SUBROUTINE TO * 30 REM * CALCULATE N TO 2 D.P. ы 40 КЕМ * i 50 REM * * * * * * * * Lines of asterisks provide visible dividers between sections of program. Use comment in the program and in the output to the screen or printer. Use blank REM lines as separators in the program. For large programs write a reference document: (1) Describe the algorithm you used. If it is not original you should include a note of its source, author, version, and type of computer it was written on. (ii) Explain how you wrote the program, the reasons for writing it, the type of computer used and memory required. (ii) Make a note of areas that may need improving, or could be modified for different purposes. (iv) Which modules are general (menus, subroutines), and which require specific kinds of input. (v) Explain the scope and limitations of the program. (vi) Include your name, and the date of production. List the tests you made and data used. Reproduce some of the results of the tests. List performance tests (e.g. how long it takes the program to run). Give user instructions and reproduce the output of a run and explain to the user how he uses the program. Give the program characteristics. Explain any abnormal behaviour of the program (e.g. response to bad input). Write a brief USER GUIDE. This is mot for the computer expert. It should explain: — the purpose of the program — the algorithm — how to run the program — what input is needed — what results are printed — how to use the menu (if included) O5: THE COMPLETE PROGRAMMING METHOD SUMMARY: THE STRUCTURED PROGRAMMING METHOD 1. | PRODUCE THE ALGORITHM State the Problem fully 1.4 1.3 1.3 1.4 1.1.4 1,2,2 State the problem Understand what is to be done Research the Problem 1.2.1 1,24% 15,4 Research апа analyse the problem to see how the computer can handle it Identify all formulae and relations to be used. Identify all data involved Design the algorithm Use top down structured methods: 152,1 1,5,2 1.5.3 1.3.4 1.2.9 1.3.6 Break the problem up into sub-problems ог modules. Use a structure diagram or tree diagram to help in breaking down the problem. Start classifying modules or parts of modules as: INPUT PROCESSING OUTPUT Utilise the fundamental control structures in the modules — Decision structures — Transfer structures — Loops - Subroutines - Nested structures — Subprograms Set up a DATA TABLE in which all data types are classified as Variables Constants Counters Functions - if using a Spectrum and the DEF ЕМ instructions Define the algorithm further until coding it into a BASIC language program is an easy and obvious exercise. Describe the algorithm in Pseudocode and Flowchart form 1.4.1 1.1.2 1.4.3 Write out the final algorithm (now in modular form) in small steps in an abbreviated English style called Pseudocode. Each module should be treated separately and !abelled. Illustrate the logical flow of control in the algorithm by constructing a flowchart. Test the algorithm, if necessary using a hand trace or walk through. 213 2. 2.1 Code the Algorithm in SINCLAIR BASIC 2.1.1 Code on a direct basis from the pseudocode or flowchart description in line numbered BASIC statements, module by module. 2.1.2 Implement the fundamental control structures, used in their SINCLAIR BASIC versions. 2.2 Debug and Test the Program 2.2.1 Debug the Program. Check the program variables against your algorithm test. Correct syntax, run time, and logical errors. 2.2.2 Test the program for further logical errors. Run the program with sample data. 2.3 Document the Program For a full documentation, you should: 2.3.1 Produce a programmers’ guide consisting of: pseudocode flowchart variable table or data table program listing test results or sample printout. 2.3.2 Detail the steps that producing the program involved. 2.3.4 Write a user guide. 214 PROGRAMMING: SUMMARY OF METHOD IN FLOWCHART FORM This provides a diagrammatic version of the summary of structured START FIND OUT WHAT YOU HAVE TO DO. programming: STATE THE PROBLEM DRAW A STRUCTURE DIAGRAM OF HOW YOU ARE GOING TO SOLVE THE PROBLEM. (THE ALGORITHM ) WRITE A DESCRIPTION OF THE ALGORITHM. PRODUCE A FLOWCHART CONDUCT A WALKTHROUGH ERRORS ? No В) 215 CODE INTO BASIC FIND ERRORS AND CORRECT RUN A TEST ERRORS ? No TEST FOR RUN TIME & LOGIC ERRORS DOES IT DO WHAT YOU WANT IT TO DO? No Yes IS THERE MORE YOU NEED TO KNOW ABOUT THE PROBLEM? TEST FOR EXCEPTIONS & GET SOMEONE ELSE TO TRY IT OUT. THIS PROBLEM NEEDS A RE-THINK. PUT EVERYTHING ELSE ASIDE, AND DON'T RUSH ERRORS 2 No WRITE DOCUMENTATIO OF HOW IT WORKS, FLOWCHARTS AND DOCUMENTATION OF HOW TO RUN THE PROGRAM. END AN EXAMPLE OF STRUCTURED DESIGN 5 2. 2. 4. Problem Statement Write a program that computes and prints the Average or Mean (M) and Standard Deviation (S) of a collection of N data items. To compute SŠ use the formula: Standard Deviation = Sum of Š A of Items) _ (Mean) Find out what we have to do (research the problem) We are given most of the information in the question but we are missing some. It does not tell us how to compute the Mean or Average. This is given by the formula: (Sum of all numbers) Mean = N We now have all the information, we need to start designing the algorithm. What is involved in this problem The outline procedure we can now define: a) We have to INPUT the numbers, and b) Perform two calculations on these numbers. First we calculate the Mean and then use the Mean value to calculate the Standard Deviation, then c) Output the results. Design the algorithm This gives the detailed procedure for the steps needed to solve the problem: a) INPUT The numbers are going to be input into an array because they will be needed twice in the calculation module. b) 1. Calculate: the Mean — Add all the numbers in the array and divide by N. 2. Calculate: the Standard Deviation - Total the squares of all the numbers in the array. Use the formula to calculate S. c) Output: the Results — The results will be printed on new lines with the words MEAN = and STANDARD DEVIATION = followed by their values. 217 5. The Tree Diagrams 1. Compute and print Standard Deviation and mean Results Each of modules 1.1, 1.2 and 1.3 will be subroutines. These will be called in the appropriate sequence by the main program module. INPUT 1.14.2 1.143 ASK HOW MANY INPUT N NUMBERS NUMBERS AND INPUT N 1.1.1.1 DIMENSION 1.1.3.2 ARRAY ; FOR I-1 TO N, Y(50) INPUT Y(I) FIND MEAN AND STANDARD DEVIATION 1.2.4 1.25.34 ^ c CALCULATE STANDARD FIND MEAN DEVIATION 1, 2.1. 2 SUM ALL DIVIDE SUM BY NUMBER ELEMENTS OF ELEMENTS FOR I = 1 TO N LET MEAN = SUM DIVIDED BY N LET SUM = SUM + Ү(І) 218 1.2.2. CALCULATE STANDARD DEVIATION 1.2.2.1; ls£s2. 2. CALCULATE SUM OF USE FORMULA TO THE SQUARES CALCULATE STANDARD DEVIATION ГЕ ТУРУР PI UM PX INITIALISE FOR EACH VARIABLE ELEMENT GET SQUARE, ADD TO TOTAL LET SUM HN FOR I=] SQR-SUM TO N SQR«Y(I) **? ( f ON SPECTRUM) Led OUTPUT RESULTS lesel PRINT "MEAN = "; MEAN 1.3.2 PRINT "STANDARD DEVIATION = '5S 219 6. The Flowcharts The Main Program module flowchart: GOSUB INPUT SUBROUTINE GOSUB PROCESS SUBROUTINE GOSUB OUTPUT SUBROUTINE 220 The Input Subroutine flowchart: ENTER CREATE ARRAY Y(50) PRINT "HOW MANY NUMBERS?" INPUT N INPUT NUMBER Y(I) RETURN The Processing Subroutine flowchart: ENTER LET SUM = SUM + LET SUMSQR LET SUMSQR ET S=SQR (SUMSQR/N) ( - (MEAN**2) ) SPECTRUM FORMULA USES 7, NOT **, RETURN 222 The Output Subroutine flowchart: ENTER PRINT MEAN PRINT "STANDARD DEVIATION=" PRINT RETURN 223 7. The Program ед The Мат Program Моаше REM "SDEVIATIDN" FEM 339 9 3 3 9 ЗЕ ЗЕ ЗЕ C 3 9€ 93639963 жҰМАТМ FROGRAM MOLD жж REM **INFLUT DATA жж GOSUE 100 REM **CALCILATE* GOSUE zoo REM ##FRINT RESLULTS3* BOSE 400 = TOF КЕМ **ENI! MAIN жж 5 ы ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ 7.2 The Input Subroutine Module 95 100 110 120 130 140 SQ 160 170 120 190 КЕМ жж А ЗЕ ЭЕ ЭЕ ЭЕ ЖЕ Ж X*INFUT SUBROUTINE жж DIM Y(S05 FRINT “HOW MANY NLMEEFRZ?'": INFLIT N FRINT N FOR Ізі ТОМ INPUT YLI) PRINT ҮСІЗ;" "3 NEXT I RETURN REM *#*#END INFUT SUE жж аз 7.3 The Calculation Module 200 210 220 220 240 220 260 270 290 290) 300 210 —O FEM 339 3 € € 3C 9€ 9€ 9€ 9€ 9€ 3€ 303030 3E 3E HE XxCOLCULATION SUE жж SUM=0 FOR Ісі ТОМ LET SUM=SUM+Y C1) NEXT I LET MEAN=SUIM/N LET СИМЕПК-О0 ЕПЕ Ісі TON LET ФШИМЕОПЕ-СИМФОЕ-һ (Y (I) X 2 NEXT I LET $= Sik (MEAN жж ЕЕТМЕМ LET [ ^ Spectrum] 2⁄2 ССӘПМЕШЕ/М2- 29) FEM **END CALC ‘Sue мен JC 3 3C 3C 30 3636 Ж 9C EE EE 7.4 The Output Module 400 REM 33939 9c X X 3€ 9€ 3C € 9€ 9€ 3€ EHH #*H0UTFUT SUBROUTINE жж 410 PRINT 420 FRINT "МЕАМ-“?МЕАМ 430 PRINT 224 440 PRINT “STANDARD DEVIATION 450 RETURN 460 REM **END OUTPUT SUB жж 333€ CICERO JEDE E EXER ЭН 8. Documentation 1) This program will compute and print the Mean and Standard Deviation of a collection of data items (numbers). 2) It allows for a maximum of 50 items to be entered. You can increase the size of array Y if you wish to deal with more data. 3) The numbers can be of any size, positive or negative, to the limit of the computer's handling capacity. This is large — you will not exceed it. 4) To run the program key in RUN, and enter numbers one at a time, presing NEWLINE (ENTER) after each one has been keyed in. Sample run to find Mean and Standard Deviation of 30, 31, 22, 5, бу 7, 30, 12. 22, 3: HOW MANY NUMBERS ? 10 20 31 325 6 7 10113 27 5 MEAN = 16.4 STANDARD DEVIATION = 11.45603 Exercise The example program to compute and print the standard deviation of a set of data items does not include a pseudocode description of the algorithm, and the documentation process is incomplete in other ways too. i 2, Complete the programming procedure by doing the following: Write out a pseudocode description of the algorithm. Perform a pre-coding walk through, checking the values of the variables, counters and expressions for each subroutine module. Key in the program and debug it. Insert breakpoints in each subroutine and perform a program trace. Insert PRINT statements to print out values of variables, counters and expressions. Obtain a program listing from the printer and run the program for a sample set of data. Keep a copy of the printer output. Document the program fully in your notebook. 225 SECTION P: THE CHARACTER SET AND CODES Pi: The ZX81 Character Set and Codes CODE/CHR$ CODE/CHR$ Ü - K] 49 L 1 F] 50 M E ГЛ 51 N 3 = 52 O 4 kl 53 P 5 D 55 r0 от 55 R 7 P 56 S o B 57 ў 9 ШЫ 58 U uw m 59 V 11 n 60 W 12 £ 61 x 13 $ 62 Y 14 : 63 2 15 ? 64 RND 16 ( 65 INKEY£ 17 66 PI 18 67 19 68 20 - 69 21 4 70 22 = 71 23 * 79 24 / 73 95 74 МОТ 26 75 USED 27 | 76 28 0 77 29 1 78 30 2 79 31 2 80 32 + 81 33 5 82 34 6 83 35 7 84 36 8 85 37 9 86 38 A 87 39 B 88 40) С 89 41 D 90 42 E 91 43 F 99 44 * 93 45 H 94 46 I 95 47 J 96 48 K 97 226 CODE/CHR$ 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 NOT USED + Å <> GRAPHICS EDIT NEW LINE (ENTE RUBOUT (DELET K/L Mode FUNCTION NOT USED NUMBER CURSOR БЕЙБЫТ” лы | ТЫШ inverse `` Inverse £ Inverse $ Inverse : Inverse ? Inverse ( inverse ) inverse > CODE/CHR$ 147 inverse < 148 inverse = 149 inverse + 150 inverse — 151 inverse * 152 inverse / 153 inverse ; 154 inverse , 155 inverse . 156 inverse 0 157 inverse 1 158 inverse 2 159 inverse 3 160 inverse 4 161 inverse 5 162 inverse 6 163 inverse 7 164 inverse 8 165 inverse 9 166 inverse À 167 inverse B 168 inverse C 169 inverse D 170 inverse E 171 inverse F 172 inverse G 173 inverse H 174 inverse I 175 inverse J 176 inverse K 177 inverse L 178 inverse M 179 inverse N 180 inverse O 181 inverse P 182 inverse О 183 inverse R 184 inverse S 185 inverse T 186 inverse U 187 inverse V 188 inverse W 189 inverse X 190 inverse Y 191 inverse Z 192 тар 193 АТ 194 ТАВ 195 (МОТ USED) 196 CODE 197 VAL 198 LEN 199 SIN 200 COS 201 TAN 202 ASN CODE/CHR$ 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 227 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ACS ATN LN EXP INT SOR SGN ABS PEEK USR STR$ CHR$ NOT жж OR AND < = > = <> THEN TO STEP LPRINT LLIST STOP SLOW FAST NEW SCROLL CONT DIM REM FOR GOTO GOSUB INPUT LOAD LIST LET PAUSE NEXT PI PRINT PLOT RUN SAVE RAND IF CLS UNPLOT CLEAR RETURN COPY Of the non-printing characters, those that are used, but print a question mark, are the following: 116-121 inclusive 126-127 Inclusive (NOTE: 5 1s the question mark.) 192 is the Quote image character, which prints a single quote. The character set is coded with the numbers 0 to 255. This, you may recall, is the number of values held in a single byte. The characters can thus be accessed with a single byte identification code. This is also the reason why some codes are listed, but have no character associated with them. The same is true of the Spectrum character set, which follows. P2: Spectrum Character Set and Codes Code Character Code Character Code Character 0 35 ж 70 Е 1 36 $ 71 G 2 37 % 72 H 3 not used 38 & 73 I 4 39 | 74 Ј 5 40 ( 75 K 6 PRINT comma 41 ) 76 ІР 7 EDIT 42 it M 8 cursor left 43 + 78 N 9 cursor right +} ; 79 О 10 cursor down 45 — (minus sign) 80 P 11 cursor up 46 ; 81 о 19 DELETE 47 / 82 R 13 ENTER 48 0 83 5 14 number 49 1 84 d 15 not used 50 2 85 U 16 INK control 51 3 86 V 17 PAPER control 52 4 87 W 18 FLASH control 53 5 88 x 19 BRIGHT control 54 6 89 Y 20 INVERSE control 55 7 90 Ж 21 OVER control 56 8 91 [ 22 AT control 57 9 92 / 23 TAB control 58 : 93 ] 24 59 š 94 f 25 60 < 95 aa 26 61 = 96 £ 27 not used 62 > 97 a 28 63 ? 98 b 29 64 @ 99 C 30 65 A 100 d 31 66 B 101 e 52 space 67 C 102 f 33 ! 68 D 103 g 34 69 Е 104 h 228 Code Character Code Character 105 i 159 (p) 213 MERGE 106 j 160 (q) 214 VERIFY 107 k 161 (r) 215 BEEP 108 l 162 (s) 216 CIRCLE 109 m 163 (t) 217 INK 110 n 164 (u) 218 PAPER 111 о 165 RND 219 FLASH 112 p 166 INKEY$ 220 BRIGHT 113 q 167 PI 221 INVERSE 114 r 168 FN 222 OVER 115 S 169 POINT 223 OUT 116 t 170 SCREENS 994 LPRINT 117 u 171 ATTR 295 LLIST 118 у 172 АТ 226 STOP 119 w 173 TAB 227 READ 120 x 174 VAL$ 228 DATA 121 y 175 CODE 229 RESTORE 122 2 176 VAL 230 NEW 123 { 177 LEN 231 BORDER 124 | 178 SIN 232 CONTINUE 125 } 179 COS 233 DIM 126 ~ 180 TAN 234 REM 127 © 181 ASN 235 FOR 128 т 182 ACS 236 GO TO 129 а 183 ATN 237 GO SUB 130 P| 184 LN 238 INPUT 131 = 185 EXP 239 LOAD 132 n 186 INT 240 LIST 133 e 187 SOR 241 LET 134 a, 188 SGN 242 PAUSE 155 ШТ 189 ABS 243 NEXT 136 m 190 PEEK 244 POKE 137 =" 191 IN 245 PRINT 138 B 192 USR 246 PLOT 139 p 193 STR$ 247 RUN 140 == 194 CHR$ 248 SAVE 141 all 195 NOT 249 RANDOMIZE 142 L. 196 BIN 250 IF 143 Kj 197 OR 251 CLS 144 (a) 198 AND 252 DRAW 145 (b) 199 = 253 CLEAR 146 (c) 200 = 254 RETURN 147 (d) 201 <> 255 COPY 148 (e) 202 LINE 149 (0) 203 THEN 150 (g) 204 ТО 151 (Һ) 205 STEP 152 (i) 206 DEF FN 153 (j) 207 CAT 154 (k) { user 208 FORMAT 155 (1) ( graphics 209 MOVE 156 (m) 210 ERASE 157 (n) 211 OPEN # 158 (o) 212 OPEN # 229 There is an important point to be noted with regard to the Spectrum character set, which does not apply to the ZX81. Among the Spectrum character set, codes 16 to 23 are control characters which are used to specify certain attributes of the character cell for printing purposes. These require arguments within a certain range (0 to 9 for colours, or 0 and 1 for on or off, etc.). Codes 6 to 14, 22 and 23 are also control characters for printing and editing. The problem with using CHR$ with these control characters is that they can be used in programs, and are then called by inserting, e.g. CHR$ 20, followed by the argument. This means that a simple call to PRINT one of these CHRS will cause the computer to think it is being given an instruction, and the syntax demands an argument. If this is not forthcoming after the CHR$, or the argument is in the wrong range, an error message results when the Spectrum cannot do what it thinks it is being asked to do. Some of these control characters, however, for colour (dealt with in Section W), and also for print control can be usefully placed in programs. If we take CODE 8, which is a cursor control character, we can write a program like this: 10 PRINT ‘‘SIN”’; 20 PAUSE 50 30 PRINT CHR$ 8;CHR$ 8; “АСКЕПр” The CHRS 8 instructions in line 30 backspace the cursor twice, re- setting the PRINT position, so that “АСКЕР” overprints “ТМ”, The upshot of this is that we cannot print out the character set of the Spectrum completely, but must start from CODE 24, after the control characters. This is no great loss, since they print (or would print, if you could get them to!) either a space or a question mark. Remember these control characters, though, as they can sometimes be useful in a program, although mostly it is far more convenient to use the BASIC instructions. For example, we can use CHR$ 23 instead of TAB: 10 PRINT CHR$ 23;10; “ТАВ CONTROL" This is not an advantage over using TAB! However it does show how these characters are used by the computer- it inserts them into program listings where the control function (e.g. T'AB), has been used. TAB itself does not have a control function, and needs CHR$ 23 placed after it to work. P3: Characters The ZX81 and Spectrum have a character alphabet consisting of 256 items which include numeric characters, alphabetic characters, keywords, instructions, commands, operators, graphics and inverse graphics symbols and other symbols. As 230 seen in the tables in the previous Units, of these 256 items some are not used at all, and some are non-printing (i.e. control characters). In Appendix III the ZX81 character codes are laid out by character type and their position on the keyboard. Spectrum codes are referenced alphabetically in Unit W1. The CODE (occupying a single byte) identifies each character uniquely for input/output purposes – i.e. input from the keyboard and output to the screen or printer. The ZX81 has a non-standard character set unique to the machine. The Spectrum has a character set in which the characters used have the codes of the ASCII character set (an internationally agreed standard) for the most part. Non-standard ASCII characters are the symbols for £ and ©, and the graphics characters. Р4: CHR$ and Code The purpose of the instructions CODE and CHR is to convert from the code to the character and vice versa. The ZX81 and Spectrum have different character sets and codes, but the instructions work in the same way. CODE CODE is a function that takes a character or string and gives as a result the numeric code that the character (a single letter string, or first character in a string) cor- responds to. For example: CODE S gives 56 on the ZX81, 83 on the Spectrum CODE “ABCD” gives CODE А, 38 on the ZX81, 65 on the Spectrum CODE X$ gives the code of the first (or only) character in X$ CODE D$(3) gives the code of the third character in D$. CHR$ CHR$ (N), where N is a numeric expression with a value 0 < = N < = 255, is a function that gives as a result the single character whose code is N. CHR$ does the opposite of CODE. For example: CHRS (A + B + C) CHRS$ (X/Z) CHR$ (INT(RND * 255)) CHR$ 36 gives 8 on the ZX81, $ on the Spectrum 231 To see the inverse relationship of CHR$ and CODE, key in the following as direct commands: PRINT CHR$ 50 will print M on the ZX81, 2 on the Spectrum PRIN T CODE 52" ° will print 30 on the ZX81, 50 on the Spectrum PRINT CODE CHR$ 50 will print 50 PRINT CODE “A” will print 38 on the ZX81, 65 on the Spectrum PRINT CHR$ 38 will print A on the ZX81, & on the Spectrum PRINT CHR$ CODE “А” will print A The next program will print out all the characters used on the ZX81. 10 FOR Е=0 TO 255 20 SCROLL 20 PRINT Е, CHR F 40 NEXT F For the Spectrum, as noted above, we must miss out some CHR$ and line 20. Line 10 must read FOR F = 24 TO 255. Key it in and run it. Add: 3:9 LPRINT F; TAE à: CHF F to get a printer listing. A better program (since it uses less printer paper!) but one with an expression you won't understand until we cover logic, is this one: 10 REM ##CHARACTER ЕТЖ 20 LFRINT "CODE/CHE$": TAB 10; "CODE/ICHR$":; TAB zZO:"CODE/CHRE$" 30 FOR Е=0 To 85 40 LFRINT F? ТАЕ 4; CHES F; ТАБ 10;F+sé; TAE 14; CHES$ CF+ie); ТАЕ 20% (F+172 AND F+172<25693; TAE 24; CHES (F+17Z AND Е+172<256) ou NEXT F Use these lines for the Spectrum version: 20 FOR Ғ-24 To 77 40 LPEINT F; TAE 4; CHES F; TAE 10:F*77: ТАР 14: CHES (Е%773; TAB 20:Е+154; TAE 24: CHES (F+154) Exercises 1 Key in and run the following programs. You may find some surprising results, due to the control characters, on the 232 Spectrum. No harm will be done. (a) 10 FOR F = 0 TO 255 (Spectrum: FOR Е = 24 ТО 255) 20 PRINT CHRS F; 30 NEXT F Notice that the word characters print with the spaces that your computer automatically inserts in program lines. (b 10 RAND 20 PRINT CHR$ INT (128* RND + 128) 30 GOTO 20 (c) 10 INPUT A$ 20 PRINT A$, CODE A$ 30 GOTO 10 (d) 10 PRINT “INPUT STRING OF 6 CHARACTERS" 20 INPUT A$ 30 FOR F =1 TO 6 40 PRINT A$(F), CODE АЖЕ) 50 NEXT F (e) 10 RAND 20IF INT (RND*2)=1 THEN PRINT CHR$ INT (RND*128) 30 IF INT (RND*2)-0 THEN PRINT CHR$ (INT(RND*128) + 128) 40 GOTO 20 (f 10 RAND 20 LET A$ = CHR$ INT (RND* 255) 30 SCROLL 40 PRINT CODE A$, A$ 50 GOTO 20 In this last program, Spectrum owners can omit line 30 and simply respond to the Scroll? prompt by pressing ENTER. Write a program that given a number (code), will check that 0 < = code < = 255, and will print out the character. On the Spectrum, the program should print “CONTROL CHARACTER” if the CODE is between 6 and 23. Write a program that when given an alphabetic character as an input will print out the next in the alphabet. If the character input was ‘Z’ then ‘A’ should be printed. SECTION О: GRAPHICS Q1: More Printing Since we dealt with the PRINT instructions, you have been introduced to other statements that can be used with the PRINT statements for format and manipulation. Loops are of use in printing. For instance we can set up an empty string with 32 spaces and use it to clear different areas: 20 LET A$ = ‘‘(32 врасев)” ЖІТІ ӘЛГІ 100 FOR Х-11 ТО 21 110 PRINT АТ X, 0; A$ 120 NEXT X will clear the bottom half of the screen, and we could use it repeatedly, as a subroutine, if we wished. We then avoid using CLS, which would mean re-printing anything that we wanted to keep on the screen. Except for numbers, anything we wish to print must be in the form of a string, either between quotes, a string variable, part of a string array, or a CHR$(X) instruction. Obviously any operations or functions used with strings may be useful, and in the same way as: 10 PRINT (1 + 3) prints 4, we can use: 20 PRINT A$ (X TO Y) to extract the desired characters of A$. Enter and run this program 10 LET A$-"ABRACADAEEA" 20 LET L= LEN ñ$ 30 FOR X=1 TO 6 40 PRINT TAE 10+X;ASCX ТО Lela}? 20 NEXT X Remember that numbers can always be treated as strings, and vice versa, using VAL and STR$. This is often useful for formatting numbers. For example, with a number X, this program: 234 10 LET A$="0000" 20 LET BS= STRS X ЗО FOR F-1 Tü 4 40 IF LEN B$4F THEN GOTO 70 20 LET A$(CFD-E$CF? &O NEXT F 70 PRINT A$ will print (һе first four digits of any number, ог follow (һе number with zeros if less than 4 digits. Change the zeros to spaces, and you have a number string that will overprint any other string however many digits are in the original. Code the program in with A$ = (4 spaces)’ and try it. As it is, you wil have to enter X as a direct command (LET Х= 123, then NEWLINE/ENTER) and then use GOTO 10, since RUN would clear the variables (in this case, the value of X you have just entered). This principle can be expanded. Here is an example of a subroutine used to justify numbers and print them in the position required for the decimal places to be in the same column: 10 REM "FORMAT" 20 REM *FORMAT SUBROUTINE For *NUMEERS ж 30 REM #COLUMN NUMBER ЕСЕ + *#DECTMAL РАСЕ + 40 LET t=12 S0 REM *INITIALISE GOSUB* ео LET ҒОЕМАТ-УООО 70 REM *NUMBER* во INPUT М1 7O REM #*#INITIALIZE NUMEER* 100 LET N=N1 110 GOSUE FORMAT 200 REM *MORE NUMBERS + 210 FOR ісі TQ 4 220 INFUT N 220 GOSWE FORMAT 240 NEXT L 2020 GOTO 999 2770 REM HHH EEE Xe SIE ROUT INE жж 7000 LET N$- STF$ М 9010 LET Р=0 7020 FOR F=1 TO LEN МФ ЭО20 IF МФ(ҒО-"." THEN LET F-F 7040 NEXT F 2050 IF F=1 THEN LET N$="O"+N% 7060 LET F=F+(P=1) 7070 IF F=0 THEN LET F= LEN N$+1 7020 FRINT TAE (C-F+1)7N% vOTO FETLIFN 7100 REM ЖЖЕМПЕПЕ ЕЕ € 3€ 9€ 3€ 9€ 3€ 3€ 92999. SIUF Lines 10 to 240 are a main program to initialise and provide numbers for the subroutine. Notice it adds a 0 if the number is a decimal. Line 235 9030 sets a marker for a decimal point in the first letter of the number string, and adding а 0 is done in line 9050. 9060 uses the logical value of (Р = 1) to add 1 if a zero was added, i.e. if P = 1 is true. This will be explained in the Section on Logic, but the line is equivalent to IF P = 1 THEN LET P = 2. Check this by trying both versions of the line. Line 9070 adjusts the length of the string if there is no decimal place found (i.e. if the number was an integer). 9080 prints the number in the correct column. The next program shows a simple way of tabulating results, using a loop: 10 PRINT “МО.”;ТАВ 4;‘SSOQUARE”’; TAB 12; "CUBE -TAB 20“ RECIP” 20 FOR N=1 TO 10 30 PRINT N;TAB 4;N*N;TAB 12;N**3; ( 1 on Spectrum) TAB 20;1/N 40 NEXT N NO. SQUARE CUBE КЕСІР 1 1 1 1 2 4 8 0.5 3 9 27 0.33333333 4 16 64 0.25 3 25 125 0.2 6 36 216 0.16666667 4 49 343 0.14285714 8 64 512 0.125 9 81 {29 0.11111111 10 100 1000 0.1 It is important to remember that numbers are output with 8 figures and allow the appropriate space. An alternative is to decide how many figures you want and use the INT function. For example, we can replace 1/N in line 30 by INT(1E4*(1/N) + .5)/1E4 , and get a printout like this: NO. SQUARE CUBE КЕСІР 1 1 1 1 2 4 8 0.5 3 9 87 0.3333 4 16 64 0.25 5 25 125 0.2 6 36 216 0.1667 7 49 343 0.1429 8 64 212 0.125 9 81 729 0.1111 10 100 1000 0.1 236 Using the E notation allows easy definition of the number of decimal places, without the possibility of missing a zero as, for example, if we used INT(10000*(1/N) + .5)/10000, since using 1E4 gives four d.p., 1E3 three d.p., etc. In using this, be careful with the bracket placing, as INT(1E4*(1/N)) + .5/1E4 will not round! Try both the correct and Incorrect versions in the program. You should note that: With PRINT TAB C; or PRINT AT L,C instructions L апа С can be dependent or calculated variables. For example: PRINT TAB (X*2)/3; PRINT AT 10, 20/X; Try these: 10 FOR X=1 TO 5 20 PRINT AT X, X. * 2:X 30 NEXT X 10 FOR X -1 TO 5 20 PRINT TAB X * 2X 30 NEXT X An automatic INT function operates with PRINT AT instructions. For PRINT AT (L), (C); if (L) and (C) > nand < n +1, (1) and (C) = n For example: PRINT АТ 3/2, 10.5;°°...”’ equals PRINT АТ 1,10;°°...”’ Try this: 10 FOR X - 1 TO 10 20 PRINT AT X, X/2; X 30 NEXT X The AT function rounds down, exactly as if we had used PRINT AT X, INT (X/2); X as line 20. PRINT TAB(N), where N is non-integer, rounds to the nearest integer. TAB N, where N is between X and X + 1, gives TAB X if N< X+ .5 and TAB X+ 1 if N2- X + .5. For example TAB (1.3) =TAB 1 TAB (1.5) = TAB 2 237 To see the difference, RUN both these programs, use COPY to get a printout, and compare the results. 10 FOR X=0 TO 10 20 PRINT TAB X/2;:X 30 NEXT X 10 FOR Х=0 TO 10 20 PRINT ТАЕ INT (X/2);X 30 NEXT X You must also watch for arithmetic mistakes in calculating the PRINT position. For instance: 10 FOR X=0 TO 10 ZO PRINT TAB 20/Х%Х 20 NEXT X is not going to get past line 20 the first time round! Why? This next example illustrates the use of PRINT AT to give changing display. A die is rolled and we wish to display its value for each of a series of throws. In addition we require cumulative values after each throw. Thus each time line 90 is reached it overprints line 70 and vice versa. Similarly line 120 overprints itself after each throw. > REM "DICEROLL" 10 PRINT "NUMBER OF THROWS?" го INPUT X 20 DIM NCE) sm CLS 40 PRINT АТ 2.27 "CUMULATIVE VA LUES" o0 FRINT АТ 10,47 "1929639639696 43x d T a жан 60 FOR M=1 TO X é5 PRINT AT 1:3; "THROW"? ТАЕ 1 4; "VALUE" 70 PRINT АТ 32107 "ж". "ж" SO LET ñ= INT (ёж RND +1) 20 PRINT АТ 3:103MsA 100 LET NCA =NCAI+1 110 FOR Есі TO é 120 PRINT AT 12:4*E;N(B) 120 NEXT Б 140 МЕХТ М (М.В. Choose a relatively small value for X (say 24) or the program will take a long time to run.) 238 Exercises 1 Modify the FORMAT subroutine to round the number to 3 decimal places before determining the print position. 2 Modify your result for the exercise above to print zeros for any decimal place not filled. 3 Write a program that displays the result of throwing three dice, displaying the result for each die, and the total value for each throw. Overprint the last result with each new one, and store the total values resulting. After the specified number of throws, derive the average value for a throw. Q2: More Plotting Although the definition of the graphics on the ZX81 is low, the computer has the capacity to draw useful graphs, and most graphics processes can be illustrated. This is a program that draws a line between two specified points: 10 INPUT Xl 20 INPUT Yl 30 INPUT X2 40 INPUT Y2 50 LET X=X(2) -X(1) 60 LET Y=Y (2) -Y(1) 65 LET A=(X AND ABS X>=ABS Y) + (Y AND ABS XMAXY THEN LET MAXY=Y 70 NEXT X SO LET SY=40/MAXY Adding the following lines gives us the plot: 20 FOR X=A-A TO B-A STEP (E-A) 160 100 LET YzX*X 110 PLOT X#é0/(B-AdsY#SY 120 NEXT X Spectrum: 240 not 60 in line 90. Notice that all the function values are calculated twice. It would be neater to set up either two lists, or a two dimensional numerical array (Х(60) and U(60) ог Х(2,60)), and store the values the first time round. Try this when we have dealt with numerical arrays. Run the program, using different values of X in lines 10 and 20 and some different equations in line 5@ (and the same one in line 100). Try X**2+3X, X**3 —6X + 2, etc. ( ^in place of ** if using Spectrum). Revise the program to allow inputs in lines 10 and 20. 240 Q3: Movement and Timing We can deal with the two topics of time and motion together. We will introduce and illustrate the new functions concerned, and then look at them in combination. The first new commands (which only apply to the ZX81) are FAST and SLOW. If the screen display is to be continuous, the ZX81 has to read and print on screen the contents of the display file fifty times a second (sixty times a second in the U.S.). It can then only compute in the gaps between doing this. Up to now, we have used this continuous compute and display mode exclusively. This is SLOW mode on the ZX81. The Spectrum works in the equivalent of the ZX81 FAST mode, and displays the screen at the same time: SLOW allows a continuous screen display. Computations are performed in the intervals between reprinting the screen. SLOW may be used as a direct command or in a program line. FAST blanks out the screen, and the ZX81 computes faster, not needing to break off to display the screen. Screen display is restored when (i) the program ends (ii) the program stops to await input (iii) the program goes into SLOW mode (iv) the program is instructed to PAUSE. The screen display is updated during FAST, but only printed at a break in the program. FAST mode is used whenever it is necessary to perform a large number of calculations on the ZX81, and a screen display is not vital. To illustrate the two modes, enter and RUN this program: 10 SLOW 20 FOR X=1 TO 20 30 LET Z=X*X**X/X**X 40 PRINT Z; 50 NEXT X Line 10 is redundant, the ZX81 will already be in SLOW mode. But now change it to: 10 FAST and RUN. Change it back and, by counting, see what the difference in timing is between the two modes. You can also delete line 10, and shift between the modes by using direct commands. Note the flash of the screen when you input lines from the keyboard in FAST mode. This 241 makes it easy to tell which mode you are in. The ZX81 computer is always in SLOW mode at switch on, and if you are shifting between the two modes, using direct instructions, then the characteristic flash will let you know if FAST is the current mode. PAUSE PAUSE causes the execution of a program to halt for the time specified. The screen display is shown on the screen during the PAUSE. Pressing a key during a PAUSE will cut the PAUSE short and the program will continue. PAUSE N gives a delay of N/50 seconds (N/6@ seconds іп the U.S.) PAUSE 150 gives a delay of 3 seconds (2% seconds in the U.S.) If N>32767 the PAUSE will continue until a key is pressed on the ZX81. If N = 0 the PAUSE will continue until a key is pressed оп the Spectrum. PAUSE allows us to insert a specific delay in a program. It also allows p y prog us to cause the program to wait for a key to be pressed before the program will continue. The following program illustrates both these functions: 10 PRINT "PROGRAM START" 20 PAUSE 100 30 PRINT "2 SECONDS" 40 PAUSE 100 50 PRIN'T "4 SECONDS" 60 PAUSE 200 70 PRINT "8 SECONDS" 80 PRIN' "NOW PAUSE UNTIL KEY PRESSED" 90 PAUSE 40000 100 PRINT "END" Spectrum users must enter line 90 as 90 PAUSE 0. PAUSE is useful in programs run in FAST mode on the ZX81, since the display file is shown on the screen during a PAUSE, and we can use this directly to get a screen display for a specified time. PAUSE used the system variable FRAMES to count in units of 1/50th of a second (1/60th second in the U.S.). This is set by the a.c. power supply frequency to the ТУ monitor, which governs the number of times a second the screen display is refreshed, which is why the timing varies in different countries. When a PAUSE commences on the ZX81 the screen ‘flashes’. This can be irritating. It can be avoided by use of an empty FOR...NEXT loop, which does not produce this effect. The time delay is less precise, but for non-timing functions — providing a delay whilst instructions are read, for example - it is easily modified to suit. 242 10 PRINT "START" 20 PRINT "2SECOND DELAY" 30 PAUSE 100 40 PRINT "FOR...NEXT LOOP" 50 FOR X = 1 TO 150 60 NEXT X 74 PRINT "END" The next instruction can be used in a program line by the ZX81 only. It does not exist for the Spectrum. The definition and discussion apply only the the ZX81, but the method of achieving the same effect on the Spectrum is given below. SCROLL SCROLL moves the whole screen up one line, deleting the top line, and sets a new PRINT position at the start of the new bottom line. To see this work, try this program: 10 FOR X-1 TO 10 20 PRINT X 30 IF X25 THEN SCROLL 40 NEXT X We can use SCROLL to clear printout on the top of the screen, but we must remember that if we use SCROLL the print position changes. We can, however, use PRINT AT instructions to avoid the bottom line print position. Delete line 20 in the above program and insert: 35 PRINT AT X, 0; X Notice that we have to be careful of where we put SCROLL, and when we use it. We can use it to prevent a ‘screen full’ error message, but unless we want all lines rising from the bottom of the screen we have to specify when to use it. We can set a line to use SCROLL at the correct place: 10 FOR X=1 TO 50 20 PRINT X 30 IF X>21 THEN SCROLL 40 NEXTX Scrolling on the Spectrum is automatic, the ‘scroll?’ prompt appearing when the screen is full. When any key other than BREAK and 'N' is pressed, the screen scrolls to display the next screenful of information. To get the same effect as is produced by the ZX81 243 SCROLL instruction in a program, which can be useful, the procedure on the Spectrum is as follows: 1. The value of — 1 must be POKEd into a system variable at memory address 23692. This is done with a program line ‘POKE 23692, - 1’. 2. Something must be printed on line 21. This can be just a space, or it may be the first thing you wish to print in a sequence that will have all printing coming up from the bottom of the screen. 3. Scrolling will then occur, one line at a time, whenever another PRINT instruction is given. A simple program illustrates this: 10 POKE 23692, – 1 20 PRINT AT 21,0:“РКІМТ HERE TO CAUSE SCROLL” 30 PAUSE 50 40 PRINT “SCROLL” 50 PAUSE 50 60 PRINT “SCROLL AGAIN” The PAUSE instructions merely cause а delay to enable you to see the process properly. The PRINT item in line 20 could be a space, as long as it is something printed on the bottom line. Try this program: 10 POKE 23692, -1 20 PRINT AT 21,0;° ” (Single space) 30 FOR F=1 TO 10 40 PRINT “РКІМТ” 30 NEXT F We can use SCROLL, or the Spectrum equivalent, to create a moving screen display. Try this: For the ZX81 For the Spectrum 10 FOR Х-0 TO 30 STEP .3 10 FOR X =0 TO 30 STEP .3 20 LET L=15+14*SIN X 20 LET L=15+14*SIN X 30. PRINT TAB Ls "XX" 30 PRINT TAB L: “ZX.” 40 IF Х>6.3 THEN SCROLL 40 POKE 23692, – 1 50 NEXT X 50 NEXT X Spectrum users please note also that the POKE instruction will work if it is given as line 5 in the program, and line 40 deleted. Try it. Try this for a rocket launch: ‘O PRINT АТ 18:17: "Em ZO PRINT s "O" 30 PRINT ; ПЕШ” 40 PRINT +" ES: 90 FOR Гео TO 0 ЕТЕР -1 60 PRINT АТ ізің" 79 NEXT С 244 SO PRINT "ELASTOFF" 70 FOR X=1 TO 22 100 SCROLL 110 PRINT ж" V" _ 129 NEXT X Spectrum users need to delete line 100, and insert 85 POKE 23692, — 1. Whilst on the subject of scrolling, here is a routine that scrolls a line of text across the screen from left to right. Input a name (inverse characters look better), or a line of text, and fill out the line with some graphics characters. Lines 20, 50 and 60 fill up the line to 32 characters with black squares. The technique can be used with several lines of text, but is too slow to be useful if dealing with a full screen: = REM *INFUT А NAME* *(NICER IN INVERSE) # е REM #REPEAT IF LINE NOT *FILLEL* 10 INPUT A$ 20 IF LEN A$432 THEN GOTO 60 20 PRINT AT 10:07A% 40 LET A$=AS( LEN ASI +АФС1 TO LEN А%-1) 20 GOTO 30 ео LET A$-0$-"H" 70 HOTE 20 When you have keyed in the program, try deleting “АТ 10,0,” in line 30. This gives an effective full-screen display. Games programs often utilise interactive graphics, via the INKEY$ function. A SKETCH program as below shifts the PRINT position around. Note that on the Spectrum, INKEYS$ is not totally reliable. Add PAUSE @ to ensure it works. 10 LET X=10 20 LET Y=10 ЗО PRINT RT ҮЧ, "+" 40 LET X=X-( INKEY$ ="3" AND Х>О)+( INKEY$ ="S" AND X<31) 20 LET Y=Y-( INKEY$ ="7" AND Ү>О09%( INKEYS ="6" AND Ү5219 60 GOTO 30 This uses logical values to do a multiple operation in lines 40 апа 50, which both adds or subtracts 1 to the values of X and Y, and keeps the character within the screen limits. This could be done less efficiently by the following: 40 IF INKEY$ = ‘‘5’? AND Х>0 THEN LET X-X-1 50 IF INKEY$ = “8” AND X<31 THEN LET X-X +1 60 IF INKEY$ = “7” AND Y20 THEN LET Y-Y-1 70 IF INKEY$ = ''6" AND Y<21 THEN LET Y=Y+1 80 GOTO 36 245 Im lines 40 to 70 both conditions have to be true to execute the change in the values of X or Y. In the original example, these logical tests are combined (in the brackets) and use is made of the fact that the computer uses 1 for TR UE and 0 for FALSE. These logical values are used to change X and Y appropriately, according to which keys are pressed, but only if the values of X are within 0 — 31 and the values of Y are within 0 — 21 (i.e. within the PRINT AT range). If, for example, X is equal to 0, then in line 40 above, the combined conditions of INKEY$ = “5” (true, if it is being pressed) AND Х>0 (not true) will be false. The instruction following THEN will not be executed. Similarly, in the line LET X = X - (INKEY$ = “5” AND X20)-(INKEY$-2':8" AND X<31) each of the bracketed expressions is evaluated for truth/falsity. Only one of the bracketed expressions can be true, and if, for example, the first is true, X will become X-(1(true)) + (0(false)). Logical operations, which are of great importance, are fully covered in Section R. We could add: 35 PRINTATY,X;' ” to get a single character rather than a line of characters, but our character flickers and is not on the screen very long. A better way is to put the values of X and Y into two other variables, and use these to store the position where a space is to be printed, overprint as late as possible in the loop. 10 LET X-10 20 LET Y=10 30 PRINT AT YsX3"#" 35 LET А-Ұ 36 LET Б=х 40 LET X=X-¢ ІМКЕҮФ ="5" AND Х>09%( ІМКЕҮФ z"E" AND X431) 50 LET ҮшҮ-( INKEY$ ="7" AND Ү>024( ІМКЕҮФ ="&" AND Y<21) 55 PRINT AT AE;" " &O GOTO 30 To get automatic movement, we need to use loops. Try this: 10 FOR X=25 TO 0 STEP - 1 20 PRINT AT І1,Х; “ай АТ 12, Хх; Se” 30 NEXT X PAUSE 10 could be inserted as line 25 on the Spectrum to slow things down a bit. Our car moves, but it leaves bits of itself behind. Add a space after each of the print strings, and the trail is automatically wiped out, overprinted by the spaces. 246 10 FOR X=25 TO 0 STEP - 1 20 PRINT AT 11,X;“ „Ш "AT 12,X;' щн 30 NEXT X The alternative, which is slower (and harder on the eyes), is to use CLS, and reprint the screen. To see the effect, just add: 29 CLS Or try this (which includes, to a rather distorted scale, a gravity effect) and imagine you are Galileo: 1 REM GRAVITY DROP 10 LET Т-й 20 LET Н-й 30 PRINT AT 0,5; "MEN" 40 PRINT АТ 21,1; "----------- " 50 IF Н>21 THEN GOTO 110 60 PRINT AT Н,10; "*" 70 LET Т=Т+.25 80 LET H-INT 32*T*T/10 90 CLS 100 GOTO 30 110 PRINT AT 21,7; "*SMASH*" The next program utilises graphics to illustrate the principle of the base current flow through an NPN transistor. The flow of the main current is indicated by a moving black graphic, and the flow of the base current by a grey square. Study the program and analyse it so that you can follow it. The string manipulation is quite complex. By now Spectrum owners should have mastered converting ZX81 programs for their own machines. Remember that the values PLOTted on the Spectrum should typically be four times larger than on the ZX81 in order to get a picture of a similar size. Apart from this, *Transim' should not present any problems: 5 REM "TRANSIM" 10 PRINT "SIMULATION OF CURREN T FLOW ІМ", "+УЕ BIASED NPN TRANS ISTOR" 20 PRINT ss" PRESS 5 TO SWITCH OFF BIAZ":"CURRENT FLOW IN BASE" 119 "PRESS R TO RECONNECT " 30 PRINT »» "GRAPHICS SHOW ELEC TRON FLUOW":,:"HIT A KEY TO START 40 FALISE 4Е4 SQ CLS во FOR Fz? To 49 70 PLOT Fo? S0 PLOT F512 90 IF F276 THEN GOTO 120 100 PLOT 275F*3 110 PLOT 30,F+3 120 NEXT F 130 UNPLOT 29312 247 140 UNPLOT 27,12 150 PRINT АТ 95; "ж NEN TRANSIS ТПЕ x": ТАБ Ss "eRe Уы X ж! 160 PRINT АТ 5317: "BASE": AT 7: 17; "CURRENT ON"? АТ 14,2: "COLLEC TOR": TAB 22? “EMITTER 170 FRINT АТ 5310; ““УЕ"; АТ 18% OF +E = Мемма Р Мема -УЕ 120 REM *w*GFñFHIC STRINGS#* 170 LET A$-" BEBE BR ELE E ии" 200 LET $=" TTE E E TTE ы а 210 LET S$=" ú = mhi" 220 FOF N=1 TÜ 15 220 REM **GFñFHICS LOOPxx 240 FOR Fei TO 8 Qi IF F=1 THEN FRINT AT 7:14; " 260 PRINT АТ 16-Ез14: "B" 270 PRINT АТ 164: B$(F TO Fev; ASIF TQ F+iG) 280 PRINT АТ 7313:5%(1 TO 3); 270 IF F=f AND ІМКЕҮФ ="S" THEN 200 PRINT АТ 73143" "b AT 16-F5 14$ s "H 310 NEXT F 320 NEXT М 330 PRINT АТ 2150; "PROGRAM HALT ED. RESTART? CY OR N)" 340 INPUT ЕФ 390 IF R$ <> "Y" THEN GOTO 440 360 PRINT АТ 21:03" 370 GOTO 220 95, REM ж Ж А ХЕ Ж жжБАСЕ CURRENT OFF СИ!» 400 PRINT АТ 5:10: “ " АТ 731 3:5%6(4 ТО); АТ 7:25; "OFF" 410 IF ІМКЕУ% <> "RE" THEN GOT 410 420 FRINT АТ 5310: "+VE"; АТ 731 2С6С1 TO: 22: АТ 725: "ON * 430 RETURN 52 КЕМ ** ENDSUB 339 HHH 553555555222 440 CLS 450 REM **END PROGRAM жж Spectrum modifictions: PAUSE @ in line 40. The program uses the ‘chunky’ ZX81 plot squares to draw the outline (lines 60 to 140). Spectrum plot points could be used, but strings of the graphics characters on keys 1 to 8 would be better. Refer to the screen diagrams in Unit M2 for the positions on screen requiring printing. 248 Exercises 1. For ZX81 users: Computer performance in terms of speed is compared by benchmark tests. Write a program that loops 500 times, performing a calculation each time. Run it in FAST and SLOW modes, and time it. 2. Revise the left to right scroll to work right to left. 3. Write a program that draws a ship and moves it backwards and forwards across the screen, automatically. 4. Revise the program to move the ship in response to INKEY$ input from the keyboard. 5. Write a program that uses PAUSE to display minutes and seconds. Check the clock against a watch and improve the accuracy. Q4: The Display File In order to talk about the display file, we must introduce some new concepts, which are dealt with more fully in a later section of the book (Section U). The DISPLAY FILE is the memory picture of the screen display stored in a sequence of memory locations or addresses in the computer RAM. BYTE. Each memory location in the computer stores an 8 bit (digit) binary number which has a decimal value between 0 and 255. To interact with the computer's memory, we use PEEK and POKE. We are concerned here not with the general instructions (which are dealt with in Section U) but with some specific uses for these commands. We will give a definition of PEEK and POKE here, and then discuss the use of these only in terms of some simple techniques connected with the screen display that can be of use in graphics. PEEK (M) returns the contents of the memory address (M) (a binary number) in decimal form. POKE (M),(N) inserts the value N (0 to 255) into the specified memory address, M. The display files of the ZX81 and Spectrum are organised very differently. That of the Spectrum is much more complex, due to the high-resolution PLOT screen and colour on the machine. We will deal with the ZX81 display file in some depth below, and then describe the Spectrum display file. Spectrum users should GOTO page 257, and omit the ZX81 specific section below, unless they find it interesting for 249 general information. It is useful to know the ZX81 display file system if you are Interested in converting ZX81 programs for the Spectrum, as some programs use the techniques described below. On the ZX81: Each address of the display file stores in a byte a character code, corresponding to the character to be printed on the screen. The display fille memory location differs according to the program length, since it starts where the portion of memory occupied by the program ends. For any given program the start location is constant. The DISPLAY FILE start address is stored in the system variable D-FILE, at memory locations 16396 and 16397. For the display fille memory locations: PEEK M gives a number (in decimal) which corresponds to the character code located in the memory address M. POKE puts into one of these memory locations a character code. POKE M, N puts the number (character code) N into memory address M The ZX81 has done away with much of the use of POKE in connection with the display file, because the PRINT AT function actually uses a routine in the computer that finds out where the display file starts and then POKEs to it the required characters at the correct position. To illustrate the work this saves, here is a program that puts ZX at line 1, column 10, on the screen. 10 LET D = PEEK 16396 + 256*PEEK 16397 20 LET Z=D+(32+1+11) 30 -POKE Z, 63 40 POKE Z+1,61 Note that, even though we could write the routine above more compactly (by missing out line 20 and using POKE D+ 44, POKE D +45 as lines 30 and 40) it is still rather more complicated than: 10 PRINT AT 1,10; TZS? Thus we will not use it unless we have good reason. But let’s run through what we are doing. Do not worry if you cannot fully understand all of this, you can return to this Section later, when the memory has been covered. 250 Line 10 sets D to the values of the ‘D-FILE’ system variable, which stores the memory location of the start of the display file. The address is always stored in two bytes (16396 and 16397) of memory and the second is the more significant byte (i.e. stores the higher value). Hence the *256 before the second memory location. PEEK 16396 + 256 * PEEK 16397 returns the value of the memory location of the NEWLINE (ENTER) character at the start of the display file. Line 20 counts along the screen to the position required. The value of 44 has been broken down to show the principle. The D-FILE address contains the NEWLINE (ENTER) character, which is always present at the start of the first line. We count 32 for the spaces in line 0, and then there is another NEWLINE (ENTER) character, marking the end of line 0. We want the eleventh position (column 10) along the next line, so we count 11. This gives us a value for the memory location corresponding to the desired print position. Using this, line 3@ prints Z Бу POKEing the corresponding character code into this location and similarly line 4@ puts X in the next position along. Notice that the display file has no correspondence to line and column numbers, it merely numbers in sequence: Start Column Newline (Enter) Newline (Enter) Character Character 0 1 1 "Dn. 31 (Line 0) 1 2 з ча 44, 33 34 jo 36 27 38... 66 67 MELOS) геу, Ga une ds a (ipe 41) c 03) mecs tV VP SEN es {же vd 726 727 (Line 22) DEC 5052.45 759 760 (Line 23) Fe Goan CU; 5.22 792 793 So to use this technique we only need to find the start location of the display file once, and allocate a variable to it (D in the program above), or arrange to re-use a program line with the PEEK commands. To try to make things a little clearer, try the following program: 10 LET DFILE = PEEK 16396 + 256* PEEK 16397 20 PRINT “DISPLAY FILE START ADDRESS І5”, MEMORY LOCATION ”; DFILE 30 FOR M=DFILE-8 TO DFILE + 8 40 PRINT M;TAB 10; PEEK M; TAB 18;CHR$ PEEK M 50 NEXT M Line 10 PEEKs the D-FILE memory locations, which store the number of the address in which the first NEWLINE (ENTER) character of the display file is located. If you have entered the program exactly as shown — including the space after “Memory Location’’ - line 20 will print: DISPLAY FILE START ADDRESS IS MEMORY LOCATION 16694 This is followed by a printout like this: 16686 118 ? 16687 0 16688 50 М 16689 3 EN 16690 0 = 16691 243 NEXT 16692 50 M 16693 118 ? 16694 118 ? 16695 41 D 16696 46 Io 16697 56 S 16698 53 P 16699 49 L 16700 38 A 16701 62 Y 16702 0 This shows a memory address (16686) then the character code it contains (118) and its character string (in this case 118 is NEWLINE (ENTER), and prints a “?”). Address 16687 is a space (character code 0) and a space is printed. 16688 contains the number 50, which is the line number of the last program line, and prints M. Then there is a 3 stored (which is the number of characters in the program line) and which prints the graphic character, then NEXT (character code 243), and M again, this time representing the variable М, not the number 50. Then there is a NEWLINE (ENTER) character (118) marking the end of the program. The next NEWLINE (ENTER) is at 16694, the start of the display file, and then there are the codes and characters for DISPLAY (the first words to be printed on the screen). To illustrate the use of PEEK and POKE with the display file, here is a program to draw on the screen. This does essentially the same thing as the sketch program we met earlier, but it uses the technique of POKEing characters to the display file directly, instead of via the PRINT AT function. We give a full listing here, but in fact to run it, you need only enter lines 190 to 290. 292 10 20 30 290 300 The complex looking line 280 (be careful to input it correctly) uses the same logic as was mentioned with the ‘‘Sketch’’ program. If you inspect it, after we’ve dealt with logic properly, you will see that each key that is pressed gives a different value. The equivalent lines without this technique would be: 280 281 282 283 284 285 286 287 REM “ARTIST" PRINT “DRAWS A PICTURE BY M OVING A CHARACTER IN 8 DIRE СТІОМ5" PRINT "ТО MOVE IN THE FOLLO WING DIRECTIONS PRESS THE C ORRESPONDING KEY" PRINT TAB 10; "NORTH--W" PRINT TAB 10; "SOUTH--X" PRINT TAB 10; "EAST--D" PRINT TAB 10; "МЕЅТ--А" PRINT TAB 10; "NORTHEAST--E" PRINT TAB 10; "SOUTHEAST--C" PRINT TAB 10; "SOUTHWEST--Z" PRINT TAB 10; "NORTHWEST--Q" PRINT PRINT PRINT "TO CHANGE THE CHARAC TER PRESS S THEN THE CHARAC TER THEN NEWLINE" PRINT PRINT "DON'T GO OVER THE ED GE OF THE SCREEN" PAUSE 400 CLS LET T2120 LET А5-"%" POKE PEEK 16396+PEEK 16397* 256+T,CODE А5 IF INKEYS="" THEN GOTO 250 LET BS=INKEYS LET T=T+(32 AND B$z"Z")- (33 AND BS="X")+ (34 AND B$="C" )- (34 AND B$z"Q")- (33 AND B$="W")- (32 AND В$="Е")+( 1 AND BS="D")-(1 AND B$=" A") IF BS="S" THEN INPUT AŠ GOTO 246 ТЕ В5-"2" THEN LET T=T+32 IF BS="X" THEN LET T=T+33 IF BS="C" THEN LET T=T+34 IF В5-"О" THEN LET T-T-34 IF BS="W" THEN LET T-T-33 IF BS="E" THEN LET T=T-32 IF BS="D" THEN LET 'Т=Т+1 IF В5-"А" THEN LET Т-Т-1 253 -33 -34 32 = +1 +32 +34 +33 If you look at the diagram above and the numbering of the display file, you will see how it works. — 1 or +1 move the position along a line, - 34 moves it up one line and to the left etc. All this numbering is within the display file. Line 240 PEEKs the D-FILE memory locations, adds the display file position number and POKEs into the result (a memory address in the display file) the character code for A$. Notice the speed of this program. This gives us one reason to use PEEK and POKE: to provide speed of display. Notice the warning about the edges of the screen in the program listing. When you have decided you have played with the program enough, try going off the edge of the screen. The results will not harm the ZX81, but you will probably have to switch the power off to reset the computer. All manipulations of the display file must be done with great care so as not to interfere with the NEWLINE (ENTER) characters marking the end of each line. If these are altered the computer cannot keep track of where everything should be, the display will go crazy and the program will crash. Be warned! (And be careful in your programming!) It is possible to increase the screen size of the display to give the capability to PRINT or PRINT AT on the bottom lines of the screen. The system variable (DF-SZ) at memory location 16418 holds the number of lines in the bottom half of the screen, and is normally set at 2. If we use POKE 16418,0, the bottom two lines can be used to PRINT AT. Try this program. 10 POKE 16418,0 20 - POR L = @ TO 23 30 PRINT “LINE NUMBER” ;L 40 NEXTL 50 FOR X =1 TO 300 60 NEXT X Notice that, after the delay caused by the FOR...NEXT loop, the 0/60 message appears on the bottom line as usual, and that the next command from the keyboard clears the bottom two lines. This is 254 because DF-SZ returns to its normal value on completion of a program. If we use COPY it will also not print the bottom two lines - it is only set for a normal screen size of 22 lines. We may also restrict the screen size. Key in this program: 10 POKE 16418, 28 20 PRINT “TOP LINE" 30 PRINT “SECOND LINE" 40 PAUSE 158 50 PRINT "NOW SCROLL" 60 FOR Х-1 ТО 4 70 SCROLL 80 PRINT "SCROLLED ";X 90 МЕХТ Х The SCROLL instruction now operates from the bottom line of a screen which is only 4 lines deep. This can be used to clear just the top part of the screen, leaving the rest undisturbed. Try this next program, which uses both these techniques together. (You don’t need to input the text in lines 70, 90 and 110. Just PRINT 1, 2 and 3 instead). 10 POKE 16418,0 20 FOR L=0 ТО 23 30 PRINT "LINE NUMBER ";L 40 NEXT L 50 POKE 16418,21 60 SCROLL 76 PRINT "THESE LINES" 80 SCROLL 90 PRINT "NOW CLEARED AND " 100 SCROLL 110 PRINT "REST OF SCREEN LEFT AS IS" 120 FOR Х-1 TO 300 NEXT X If entered as above, the top portion of the screen would look like this: THESE LINES NOW CLEARED AND REST OF SCREEN LEFT AS IS LINE NUMBER 3 LINE NUMBER 4 LINE NUMBER 5 LINE NUMBER 6 Unfortunately, we cannot choose a screen section in the middle of the screen (e.g. lines 6, 7 and 8) to do this with, and must use PRINT AT “(32 spaces)’’ with the lines we want to clear, or overprint directly, or POKE spaces into the relevant positions, as in this program: 10 FOR F= 1 TO 9 20 PRINT "LINE NUMBER ";F;" (16 SPACES) END" 30 NEXT F 255 40 PRINT "LINE NUMBER TO BE CLEARED ?" 50 INPUT LINE 60 LET DFILE-PEEK 16396+256*PE EK 16397 70 FOR X-1 TO 32 80 POKE (LINE-1) *33+DFILE+X,9 90 NEXT X Note that if we put: 70 FOR X=32TO1STEP -1 we get a reverse line clearance (right to left), and 70 FOR X=32 TO 30 STEP - 1 clears END, but leaves the rest of the line. Another useful system variable concerned with the ZX81 display file is the DF-CC address, locations 16398 and 16399. This holds the address of the current print position in the display file. If this address is found by using PEEK 16398 + 256* PEEK 16399 then it can in turn be PEEKed, and will give the code of the character present at the current print position. Note that the current print position is the next position to be printed. A line like 10 PRINT TAB8; “А” leaves the current print position set at the start of the next line of the display, and 19 PRINT TAB 8; A": gives as the current print position the next position after the A. To illustrate, here is a variation on the basic screen movement program we derived from SKETCH which uses the DF-CC variable. 10 LET Х-10 20 LET Ү-10 30 PRINT АТ Ү,Х; 40 LET D=PEEK 16398%256%РЕЕК 16399 50 PRINT "*" 60 LET Х-Х-(ІМКЕҮ%-"5" AND X>@) + (INKEYS="8" AND X<31) 70 LET Ү-Ү-(ІМКЕҮ5-"7" AND Y>@) + (INKEYS="6" AND Y«21) 80 POKE D, @ 90 GOTO 30 Instead of setting two variables as equal to X and Y before their values are altered (before line 50) in order to identify where to print the space which blanks the ‘‘*’’, we use variable D to store the location of the print position (line 40) and then POKE a 0 (space) into it to overprint (line 80). 256 Notice lines 30 and 40. We must set the PRINT AT position in line 30, then PEEK the DF-CC addresses, then PRINT the ‘‘*’’. The ASTEROIDS program in the program library uses the technique of PEEKing the next PRINT position to determine whether a black square occupies this position. The relevant lines are 130 PRINT AT 5,C; 140 IF PEEK (PEEK 16398 + 256*PEEK 16399) = 128 THEN GOTO 250 150. PRINT 44” Look up the program апа work out how these lines relate (о the rest of the program. If you find line 140 confusing, remember that the ZX81 evaluates expressions in brackets first. It gets the value stored in the 16398/9 addresses, which returns the address of the PRINT position, then PEEKs this address. We will now deal with the Spectrum display file, which does not have the straightforward structure of that of the ZX81, and to which PEEK and POKE techniques have little application. SPECTRUM DISPLAY FILE The Spectrum display file is organised in a very different way to that of the ZX81. This is a consequence of the high-resolution screen display on the Spectrum (256 * 176 points are plotable), compared to the ‘chunky’ graphics of the ZX81, with only 64 * 44 plot squares. The pattern of squares in any character cell on the ZX81 can be defined as a character code. On the Spectrum each individual point of the 8 by 8 grid of a character cell must be individually specified. The Spectrum display file is fixed in memory, and does not vary its location. There is no need to PEEK a system variable to find its position, as the start address is always 16384, and it is a fixed length of 6144 bytes, occupying the memory addresses up to 22527. The complex method of organisation means that it is not possible (as it is with the ZX81 and other computers), to POKE character codes to the screen and have the character specified by that code appear. Similarly, we cannot PEEK the screen to find out what character, if any, occupies a given location. Both these operations are theoretically possible, with much calculation, but not practicable. However, the speed of the Spectrum’s operations takes away much of the advantage of using PEEK and POKE on the ZX81, and we can use PRINT AT instructions to place characters on the screen, and two special Spectrum functions for finding out what is on the screen. Before introducing these instructions, here is a description of the way the Spectrum display file is organised: Each character cell has an 8 by 8 dot matrix of points, which may be ‘set’ (blacked or inked in) or not. These patterns of dots make up the 257 characters. We'll treat this in more detail later. For plotting, each point must be specified individually, and this means that the characters available in the character set do not cover the whole set of possibilities for each cell. To cope with this, the Spectrum stores each pattern of points along a 32 character cell line on the screen in a sequence of bytes. However, these are not stored in sequence down the screen. The top point sequence of each of the first eight rows of characters (lines) are stored one after the other. The second line of points in each of these 8 lines of characters is then stored, and so on until the first eight lines of the screen display have been defined. The next eight lines on the screen are then stored in the same way, followed by the bottom eight lines of the 24 line screen. To make this clearer, key in the following program and run it: 10 FOR A= 16384 TO 22527 20 POKE A, 85 30 NEXT A This puts into each byte the binary form of 85 (01010101), giving alternate plotted and unplotted (‘set’ and ‘unset’) points. You will see that the top line of points for each of the top eight lines on the screen appears, in sequence top to bottom, then the second line of points for each of these eight PRINT lines, and so on. When this sequence has finished, it repeats for the next block of eight lines, and then again for the bottom eight. You should now see why it is not easy to define a particular sequence of POKEs to the display file to get a character on screen! This is best done using PRINT AT on the Spectrum in all cases. Pixels can also be plotted, of course, and in Section W the user-defined graphics available on the Spectrum are dealt with, which enables any character cell pattern of 8*8 plot points to be defined and treated as a character which can be placed on the screen with a PRINT AT instruction. To find out what is on the screen at a particular place we use SCREENS (instead of PEEKing the display Ше) on the Spectrum. SCREENS SCREENS is a Spectrum specific function. It returns the single-character string of the character printed at the specified line and column co-ordinates. It has the form: SCREENS (L,C) PRINT SCREENS (2, 6) returns the character printed at Line 2, Column 6 on the screen. The brackets cannot be omitted. SCREENS will return the true video form of any inverse character. It does not recognise either the true video or inverse video forms of the Graphics characters. 250 Note the restriction on what SCREENS will recognise. The chunky graphics characters on keys 1 to 8 are not recognised. An empty string is returned. Run the following program to see SCREENS$ in action. After you've tried other characters, try the graphics characters and inverse video. Input PRINT LEN SCREEN$(10,10) as a direct command to see that the null string (no characters) is returned. 10 INPUT A$ 20 PRINT AT 10, 10; A$ 30 PRINT SCREENS (10,10) There is another Spectrum specific instruction that can be used to find out what is currently on the screen. This is POINT. POINT POINT returns 1 if a specified PLOT pixel is inked in (‘set’), Ø if it is not. It has the form POINT (X,Y) where X and Y are the PLOT screen co-ordinates of the point to be checked. To see the action of POINT to check if a plot pixel has been inked in, key in the following: 10 PLOT 128,88 20 PRINT POINT (128,88) 30 PRINT POINT (128,89) POINT returns 1 for line 20 (pixel plotted), and 0 for line 30 (pixel not plotted, or ‘unset’). Notice that the brackets must be placed around the X and Y expressions. Both POINT and SCREENS will, of course, work with calculated values. POINT can be used to give information about inverse characters that SCREENS will not provide. We can illustrate this simply. Key in this program: 10 PRINT “EP 20 PRINT POINT (0,175) 30 PRINT AT 10,10; Ml" 40 PLOT OVER 1;84,90 50 PRINT POINT (84,90) 60 PRINT POINT (85,90) Line 20 checks the upper left corner pixel of the character cell with the exponentiation sign printed in inverse video. This returns 1, since the pixel is set. Line 30 prints an inverse square (CAPS SHIFTed graphic 259 8), which SCREENS will not recognise. Line 40 unplots 1 pixel, using the OVER 1 statement, and line 50 checks this plot point, returning 0, since it is unplotted, and line 60 checks roughly the centre point of the black square, which returns 1. This offers us a way of checking inverse characters. You must, of course, make the correct calculations for the transfer from the PRINT to PLOT screens. You should notice two points for future use, after Section W has introduced the other Spectrum functions not dealt with in the main body of the text. One is that we referred to POINT returning 1 if the pixel was set or inked in, and when you start using colour, you should remember that POINT checks for the currently specified INK colour. For our purposes, this is black. The other is that the colour attributes that refer to a character cell when colour is used can be another source of information about the screen display. (This uses the ATTR function. See Unit W3.) 260 SECTION R: LOGICAL OPERATIONS R1: Logic Values and Numeric Values When using the logical capability of Sinclair BASIC we must distinguish between logical values and the numeric values produced by logical evaluation. We have touched upon this earlier in the book, but deferred a full explanation until now. LOGICAL VALUE is the value of an expression using the criteria: any non-zero value of the expression = ‘‘TRUE”’ a zero value of the expression = ‘‘FALSE”’ When an expression is logically evaluated it is assigned one of two numeric values: “TRUE” 1 “FALSE” 0 R2: Boolean Operators: The AND Operator AND A Examples 100 IF (A = 10) AND (B<>3) THEN GOTO 60 200 PRINT (A AND B) The AND operator (symbol ^ ) forms a logical conjunction between two expressions involving conditional operators. If both expressions are ‘‘TRUE”’ the conjunction is “ТЕСЕ”. If one or both are ‘‘FALSE”’ the conjunction is ‘‘FALSE?’’. The numeric value of “TRUE” is 1. The numeric value of “FALSE” is 0. All non-zero values аге “ТЕСЕ”, In line 100, if the relation A = 10 is “ТЕГЕ” and the relation B<>3 15 “TRUE” then control will pass to line 60. If either or both of the relations is ‘‘FALSE”’’ then control passes to the next line. In line 200 the computer will not print A + B. It will print the value of A or 0 depending on the values of A and В. Remember: All non-zero values are “TRUE”. So if A = 15 and B = 6 A = “ТЕСЕ” B = “TRUE” So the relation (A AND B) is (“ТКСЕ” AND “ТКСЕ”). So the result is logically “TR UE”. 15 is printed. If A = 16 (“TRUE”) and В = 0 (zero value – logically “FALSE’’). Then (A AND B) is ((TRUE" AND ‘‘FALSE”’’) =“ FALSE” = 0. So @ is printed. We will explain this in more detail later. 261 Truth Table for AND A | > [sees | TRUE | A TRUE A and B are conditional expressions. R3: The OR Operator OR V Examples 100 IF (A>1) OR (B = 0) THEN STOP 200 PRINT (C OR D) The Boolean operator OR (symbol v ) forms the logical disjunction of two expressions involving conditional operations. If either or both of the expressions is “TR UE” the OR disjunction is "IRUE'". If both expressions are ''FALSE"'' the OR disjunction is ‘‘FALSE’’. In line 100 if either of the expressions (A21) and (B = 0) аге “TRUE” the program will STOP. If both are **FALSE'' control passes to the next line. In line 200 if C2 10 = '"TRUE'" and D= 0 = "FALSE" С OR D=“TRUE” OR “FALSE” = ““TRUE”’ 10, the value of C is printed. If C=@ = “FALSE” and D = 0 = “FALSE” C OR D= “FALSE” OR “FALSE” = “FALSE” So @ is printed. Truth Table for OR TRUE TRUE TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE A and B are conditional expressions. R4: The NOT Operator NOT `] Examples 20 IF NOT A THEN STOP 30 IF NOT (A = B) THEN STOP 100 PRINT NOT A 262 NOT (symbol | ) logically evaluates the complement (reverse) of a given expression. In line 20, if A210 then A=‘‘TRUE”’ апа NOT А = NOT “TRUE” = “FALSE”. So in line 20 if A is 10, NOT A is “FALSE” and control passes to the next line. IfA=@ ("FALSE') then NOT A= NOT “FALSE” “ТЕСЕ” and the program stops. In line 30 if (A= B) is “FALSE”, NOT (А = В) = NOT “FALSE” = “ТКСЕ”, so program stops. In line 100 1А = 0 = ‘‘FALSE”’ then NOT А = “TRUE” = 1 So 1 is printed. If A= 29 then A is “ТКГПГЕ” and NOT А = ‘‘FALSE’’, and 0 is printed. Truth table for NOT TRUE FALSE FALSE TRUE A is a conditional expression. R5: Conditional Operators ‘There are two ways to use conditional operators in logical evaluations. 1. ‘To check the numeric value of an expression Examples 100 IF A= 3 THEN GOTO 60 200 IF B<>C THEN STOP The numeric value produced by the logical operation is not important. We are concerned only with the truth or falsity of the condition indicated іп the IF... THEN statement, which determines whether the instruction is executed. When the specified condition is present ("TRUE"), the statement after THEN will be carried out. 2. То check on the numeric value produced by logically evaluating ап expression In this case we want the numeric values, where ‘“TRUE’’=1 and "FALSE' = 0 Examples 200 PRINT A10) AND (B= 0) THEN GOTO 20 200 ІЕ(А-0) OR (В-0) THEN STOP 300 IF NOT (А = В) THEN PRINT ‘‘A<>B”’ These all mean: IF [combined result is TRUE] THEN (do it) IF [combined result is FALSE] go to the next line of the program. Using logical operations is a way of combining conditional operators in a statement. For example: IF [(condition 1) AND (condition 2) AND (condition 3)] evaluates as TRUE or FALSE] THEN...act accordingly. 60 IF ((A>B) AND (C>A) AND (D>C)) THEN STOP AND IF (CONDITION 1) AND (CONDITION 2) THEN (RESULT) TRUE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE EXAMPLE: Condition 1- My age is > 12 years Condition 2- My age is < 20 years Result – І am a teenager. IF (my age > 12 years) AND (my age < 20 years) THEN (I am a teenager). Program 10 PRINT “INPUT AGE” 20 INPUT A 264 30 IF (A>12) AND (A<20) THEN GOTO 60 40 PRINT “YOU ARE NOT A TEENAGER” 50 STOP 60 PRINT “YOU ARE A TEENAGER” OR IF (CONDITION 1) OR (CONDITION 2) THEN (RESULT) TRUE TRUE TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE FALSE FALSE EXAMPLE: Condition 1 — I earn wages Condition 2 — I get pocket money Result – I have money IF (I earn wages) OR (I get pocket money) THEN (I have money). Program 10 PRINT “INPUT AMOUNT OF WAGES AND POCKET MONEY YOU GET” 20 INPUT W 30 INPUT P 40 IF (W»0) OR (P>0) THEN GOTO 70 50 PRINT “YOU HAVE NO MONEY” 60 STOP 70 PRINT “YOU HAVE”’;W + P;‘‘POUNDS”’ NOT IF [NOT (CONDITION)] THEN (RESULT) TRUE FALSE FALSE TRUE EXAMPLE: CONDITION - I have money RESULT — I do not have money IF [NOT (I have money)] THEN (I don’t have money) Program 5 PRINT “ARE YOU A LIAR?” 10 PRINT “ІМРІУТ AMOUNT OF MONEY" 20 INPUT M 30 IF NOT (M>0) THEN GOTO 60 40 PRINT “APPARENTLY YOU DO NOT HAVE MONEY" 50 STOP 60 PRINT “YOU DO HAVE MONEY REALLY ?" 265 R7: Multiple Logic on Conditions Multiple logical operations on conditions are often useful. They take the form: AND AND AND IF [(C1) = | (C2)] к= | [(C3) ке | (C4)] THEN... Where СІ = Condition 1 C2 = Condition 2 Condition 3 C4 = Condition 4 e.g. IF [(C1 AND C2) OR (СЗ AND С4)] THEN... The above statement means that: IF conditions 1 AND 2 are obeyed OR conditions 3 AND 4 are obeyed then the combined expression is TRUE, and the instruction will be executed, i.e. either pair of conditions being both TRUE will give the result. IF (С1 AND C2) AND (C3 AND C4)] THEN In this statement all four conditions must be true to give the result. e оз I What do the following imply? IF [(C1 OR C2) AND (C3 OR C4)] THEN... IF (Сі OR C2) OR (C3 OR C4)] THEN... Notice the importance of brackets in the statements. Their placing gives a clear logical meaning to an expression. Any bracketed expression will be evaluated first. The result (““TRUE”’ or "FALSE") obtained from the bracketed expression will be used in evaluating the whole expression. A practical example of multiple logical operations on conditions would be obtaining a loan. The relevant conditions could be: C1 = Husband is over 21 years old C2 = Husband's salary is over £5,000 per year C3 = Wife is over 21 years old C4 = Wife's salary is over £5,000 per year. We can write a statement which indicates whether the bank will grant the family a loan to buy a car: IF (Сі AND C2) OR (C3 AND C4)] THEN loan granted. Exercises 1. Key in and run the program which illustrates this: 10 PRINT "INPUT AGE OF HUSBAND" 20 INPUT HA 30 PRINT “INPUT AGE OF WIFE" 40 INPUT WA 50 PRINT "INPUT P.A. INCOME OF HUSBAND" 50 INPUT IH 266 70 PRINT “INPUT P.A. INCOME OF WIFE" 80 INPUT IW 99 IF (НА>21 AND IH>= 5000) OR (WA>21 AND IW>= 5000) THEN GOTO 120 100 PRINT "NOT ELIGIBLE FOR LOAN" 110 STOP 120 PRINT "LOAN AVAILABLE" 2. Write a program which inputs four numbers and outputs a message if any of them are zero. R8: Logical Operations on Numbers The logical operations AND, OR, NOT when applied to numbers return a number as the result. The rules for the operations on two numbers X and Y are given in the following truth tables. Non-zero values may be either positive or negative. AND i.e. X AND Y returns X if Y is non-zero 0 if Y is zero. i.e. X OR Y returns 1 if Y is non-zero X if Y is zero. i.e. NOT Y returns @ if Y is non-zero 1 if Y is zero EXAMPLES: 7AND3 = 7 7 AND 0 = 0 ЭШК Л = | 267 JORO = 5 NOT 8 = 0 NOT @ = 1 Exercises 1 Key inthe examples given above as direct commands, and verify the rules of logical operations on numbers. 2 Keyin and run the following programs: LOGIC 1: 5 REM "LOGIC 1" 10 INPUT A 20 INPUT B 30 PRINT "А=";А,"В="; В 40 PRINT "A AND B-";A AND B 50 PRINT "A OR В=";А OR B 60 PRINT "NOT B=";NOT B 70 GOTO 19 Results: А-77 В A AND B=77 А ОК В = 1 NOT В = 0 li н> сл А = 77 В =Q А AND В = 0 А OR В = 77 NOT В =1 LOGIC 2: 5 REM "LOGIC 2" 10 REM **THIS PROGRAM TESTS THE LOGICAL OR OPERATOR ACTING ON A NUMBER AND A CONDITION TOGETHER** 30 PRINT "Ү-10%(7 OR А=3) " 35 PRINT 40 PRINT "INPUT A VALUE FOR A PLEASE" 45 PRINT 5@ INPUT A 55 LET Ү-10%(7 OR A=3) 60 PRINT "IF A=";A,"THEN Ү-";Үү 65 PRINT 70 PRINT "WHAT ARE YOUR CONCLUSIONS??" 75 PRINT 88 PRINT 90 GOTO 39 LOGIC 93: 2 MEM “LOGIC 3" 10 INFLT А 20 FRINT 77-(10 AND A=) 30 GOTO 10 268 R9: Priority OPERATOR PRIORITY = & >, «аб, ll 5 NOT 4 AND 3 OR Ж Priority rules are strictly obeyed. If brackets are not used properly when logical operators act on conditions the desired result will not be achieved. For example: NOT (**FALSE'' AND ‘‘FALSE’’) gives NOT “FALSE” = “TRUE” BUI NOT “FALSE” AND “FALSE” gives “TRUE” AND ‘‘FALSE”’ = “FALSE” Completely the opposite! Exercises 1 Key and and run this program, which checks priority. 10 LET A=1 20 LET B-1 30 PRINT NOT (A - 0 AND B = 0) 40 PRINT NOT A-0 AND B- 0 2 What result would the following give? PRINT 5 AND 3 OR 0 OR NOT 7 AND 4 3 Key in and run program ''LOGIC 4”, which tests priorities: REM "LOGIC 4" REM **THIS PROGRAM TES'TS MU LTIPLE LOGIC OPERATORS** 10 LET A-5 AND 3 OR @ OR NOT 7 мл AND 4 20 PRINT "5 AND 3 OR @ OR NOT 7 AND 4="; A 30 PRINT 40 PRINT 50 LET B=((4 AND 2) AND МОГ (0 AND 3)) OR ((3 OR Ø) AND (4 OR 0)) 60 PRINT "((4 AND 2) AND NOT ( 0 AND 3)) OR ((3 OR 0) AND (4 OR 0))-";В 269 R10: Logical Operations with Strings 1 Logical operations using AND, OR and NOT may be performed on conditional string expressions. For example: 10 IF (A$ = B$) AND (C$ = D$) OR (D$ = E$) THEN... 50 PRINT NOT AS = BS. 2 The AND operator may be used directly between a string and a number. For example: PRINT (A$ AND N) The result of this operation is given by the truth table. —— < ECA W EF | ULE i.e. A$ AND N returns A$ if N is non-zero and a null string if N is zero. 3 Two strings cannot be directly operated on by any logical operator because strings cannot have logical values. For example: A$ AND B$, A$ OR B$, NOT A$ are meaningless expressions. Exercises 1 Key in PRINT NOT “A” =p апа PRINT YA” = B” AND “BM = G” OR "G'a"E" to test the rules of logical string operation. Try other combinations. 2 Write a program which requests a name and then checks to see if it corresponds to several strings stored in the program, printing out a message to say if the word was found. 3 Write a program to test the truth table for A$ AND N. R11: Logical Operations Between Strings and Conditions Only the AND operator may be used. The rule is the same as for strings and numbers. A$ AND C gives A$ if C is “ТЕСЕ” A$ AND C gives a null string if C is “FALSE” C can be either a string condition or a numeric condition. 270 EXAMPLES: PRINT “А” AND 3 =3 gives A PRINT “А” AND 3 = 4 gives the empty (null) string PRINT “А” AND “В” = *B" gives А PRINT “A” AND “B” = “С” gives the null string Exercises 1 R12: Key in and run LOGIC 5, which illustrates string and condition use. 5 REM "LOGIC 5" 10 LET Х5-”АВ” 2) LET YSe"Ac* 30 PRINT (2 AND X$»Y$) 40 PRINT (7 AND X$«Y$) 50 PRINT (5 AND X$-Y$) 52 PRINT 54 PRINT 60 LET Р5-"1" 70 LET Q$="2" 80 PRINT (33 AND PS$>Q$) 90 PRINT (66 AND Р5<05) 100 PRINT (99 AND Р5-06) 102 PRINT 110 PRINT «со я ABUEL ниди м 112 PRINT 120 PRINT "AND mW que uu SW Results: Soc © < Sd SO "VAM “АСТ” AND vy] tte eet Alter the values of X$, Y$, P$ and O$ and run the program again each time. Alter the program to allow various strings and numbers to be input, and print out the relationships. Logical Operations Between Numbers and Conditions N AND C N OR C 271 Where N is a number and C is a condition: either a string condition e.g. A$ = “A” or a numeric condition e.g. B = 7 N FALSE 0 N These are the same rules as with logical operations between numbers. N AND C gives N if C is “ТЕГЕ” N AND C gives 0 if C is “FALSE” N OR C gives 1 if C is “ТЕГЕ” N OR C gives N if C is “FALSE” Exercises 1 Analyse, key in and RUN the following statements, and confirm the rules. PRINT TANDA = “A~ PRINT P AND “A” = “А” PRINT 7 AND ‘‘A”’ = “В” PRINT 0 AND “A” = “ВБ” PRINT 7 OR “A” = “A” PRINT 0 OR “A” = “А” PRINT 7 OR “А” = “p” PRINT 0 OR “А” = “В” 2 Кеуіп and run this program. Input B as 3 and 5. 10 INPUT B 20 PRINT 7 AND B= 3 30 PRINT 7 OR B=3 40 GOTO 10 R13: Applications of Logical Operators Simple conditional tests Multiple conditional tests Multibranch GOTO and GOSUB Finding maximum and minimum values Checking characters input Checking input values Testing for zero Default values COND Qo GON m 1 2 4 Simple Conditional Tests IF (Logical Operation) THEN (statement). If the logical operation is TRUE the statement is executed. AND, OR and NOT operators are used. Multiple Conditional Tests IF [(Condition 1) AND (Condition 2) OR (Condition 3)] THEN (statement). If the multiple logical operations are TRUE the statement is executed. AND, OR and NOT are used. Multibranch GOTO Routines Using this technique, control may be transferred to any of a number of statement lines. Here we use the AND routine, whose default value is zero: GOTO (100 AND C1) + (200 AND C2) + (300 AND C3) C1, C2 and C3 are three conditions. Control is transferred to line 100 if C1 is TRUE 200 if C2 is TRUE 300 if C3 is TRUE. Similarly: GOSUB (100 AND C1) + (200 AND C2) Control is transferred to: the subroutine at line 100 if C1 is TRUE 200 if C2 is TRUE 300 if C1 and C2 are TRUE and the next line, if neither are true. Key in and run this program: 10 INPUT A 20 INPUT В 30 GOTO (100 AND А=0)+ (200 А ND B=) 40 PRINT A48 50 STOP 100 PRINT "A-Q.INPUT A AND B AGAIN" 110 GOTO 10 200 PRINT "В-0.ІМРОТ B AGAIN" 218 GOTO 20 300 PRINT "BOTH ZERO. INPUT A AND B AGAIN" 318 GOTO 10 Finding Maxima and Minima Values We use the AND operator to find the maxima and minima of two numbers X and Y. 1@ INPUT X 20 INPUT Y 30 PRINT "MAX IS"; (X AND X>=Y) +(Y AND Y>X) 40 PRINT "MIN IS"; (X AND X<=Y) %(Ү AND Ү<Х) 273 or we could program this as 20 IF X >= Y THEN GOTO GO 40 PRINT "MAX="3¥:" MIN="3X FQ TUF æ ео PRINT "MAX=";X;" MIN="sy Which do you think is the best method? Finding the largest number in a list is another application. We have a list of numbers A(1) to A(N). We can compare the first two, A(1) and A(2), and put the largest of these into a variable L by the statement: LET L-(A(1)AND A(1)> = A(2)) +(A(2)AND А(2)>А(1)) We compare this value of L with the next number A(3) and make L take the larger value of the two and so on through the list. LET L=(L AND L> = A(3)) + (A(3) AND A(3)>L) The program asks us to input how many numbers will be in our list (N). We then input the numbers A(I). These are printed on the screen together with the largest value. Two loops are used, the first to input the numbers and the second to perform the comparisons. 10 REM "LARGEST" 20 PRINT "INPUT HOW MANY NUMBE 30 INPUT N 40 PRINT М 50 DIM A(N) 60 FOR I = 1 TON 70 INPUT A(T) 80 PRINT A(I);" "; 98 NEXT I 100 LET L =(A(1)AND А(1)>=А (2) )+(A(2)AND А(2)> А(1)) 1102 FOR I = 3 TON 120 LET L = (L AND L>=A(I)) + (A(I)AND A(I)> L) 130 NEXT [I 148 PRINT “LARGEST NUMBER IS " ;L Key in and run the program. This is an appropriate place to emphasise the care needed in programming logical operations. There are two things that cause problems. The first is the setting of conditions, and the second is the grouping of these conditions in a logical sequence that will produce the required result. Any line the computer does not reject because of a syntax error will produce a result. Care is needed to get the right result. This can be illustrated by the question of deriving the larger of two numbers, using AND. The problems of non-rigorous use of the logical and relational operators can be illustrated by considering the following problem. We have two numbers X 27% and Y. We know that AND can be used so that if we code a program line as LET M = X AND Х>Ү it will return the value of X if the condition is true. We want to use this to get the value of a maximum. The line above will produce zero if the condition Is not true. So we can combine two such tests in one line to get our maximum. We key in this sort of program (do it): 10 INPUT X 20 INPUT Y 30 LET MAX =X AND Х>Ү +Y AND Ү>Х 40 PRINT MAX Input some numbers and check the results. Something is wrong. Looking at the program, we see we need some brackets. As it stands, line 30 is actually a sequence of three conditions, joined by two AND operators. It reads ‘give MAX the logical value of (X) AND (X>Y + Y) AND (Y>X)’. Since all three conditions have to be true for the whole expression to be true, and since (X>Y + Y) and (Y>X) cannot both be true, we get zero. We make the expression more sensible, we hope, by changing line 30 to read: LET MAX = X AND (Х>Ү) + Y AND (Y>X). Key in this as a new line. Now try some inputs. If X is smaller than Y we get the value of X printed, and if X is greater than Y we get zero. We haven’t got the brackets right. There are still three conditions joined by two ANDs. We've changed the meaning, but not to what we actually want. If X and Y are non-zero, (X) is true, ((X>Y) + Y) is zero for smaller X, one (TRUE) for larger X, added to Y. This is non-zero, so is TRUE. If the last condition is TRUE (i.e. Y2X) then the combined expressions give X as the result. If it’s FALSE then the whole expression is FALSE and prints 0. Now we see what's wrong, we can put some more brackets in. Edit line 30 to read: LET MAX = (X AND(X>Y)) + (Y AND (Y>X)). Now try some inputs. The greater of the two numbers is returned, which zs what we wanted. If we now look at our working line, we can see (or should) that there are brackets we don’t need, although they don’t do any harm. Edit line 30 to read LET MAX = (X AND X>Y)+(Y AND Ү>Х) and check the greater value is still returned. So we're finished — or are we? Only if you didn't consider what happens if the numbers X and Y are equal. Input the two numbers as the same value and see what result you get. Both expressions are FALSE if the numbers are equal, so we get zero printed. The line should read: 30 LET MAX = (X AND X» = Y) «(Y AND Y>X). Just in case you're not convinced of the problems you can get into if you are not careful, enter the line as above and check that it works. Then edit it to read: LET MAX = (X 275 5 AND X> = Y)+(Y AND Y> = X) and input values with X>Y, YX and X= Y. This sort of problem is only avoided by carefully thinking out the result required in the case of all inputs, and checking the logic before you code it in. If there are these possible problems in a four-line program, think of the potential pitfalls in a complex one! Checking Characters Input Control in a program can be achieved using the INKEY$ statement and checking which character is keyed in using combined conditional logic operations. We have seen this used in programs earlier in the text. The following program enables the numbers on the keyboard to be used as a Joystick, allowing you to move a dot in any direction on the screen. To move the dot in the following compass directions press the desired key. 4 7 1 5 8 3 6 2 = REM "JOYSTICK" 10 REM *SPECTRUM: X=120) Y-80 20 LET X-30 30 LET Y-20 40 PLOT X,Y 50 IF ІМКЕҮФ ="" THEN GOTO 50 80 LET A$- ІМКЕҮФ 45 REM *SPECTRUM: 70 OVER 1:PLOT X«Y 70 UNPLOT X,Y 75 REM *SPELTRUM: Х<255 80 IF Х<63 AND CA$="S" DR Аф=" 1" OR Аф="2") THEN LET X=X+1 SỌ IF X50 AND (A$-"A" DR A$="2 " OR A$-"5") THEN LET X-X-1 95 REM *SPECTRUM: Y£175 100 IF Y442 AND (A$="7" DR A$=" 4" ПЕ Аф="1") THEN LET Y=Y+1 110 IF Y50 AND (A$="6" DR A$="2 " ОЕ A$z"3") THEN LET YzY-1 120 GOTO 40 276 Analyse the program. Key it in and run it. Change the program to move the dot in larger Jumps. Change the program to move the dot in sixteen different directions. Checking Input Values The OR operator can be used to check that values keyed into a program are in range. For example, we are asked to input values for variables in the following ranges: A range 0-9 B range 10 - 99 C range 100 - 999 Here is a program that checks values input: 10 INPUT A 20 IF A<@ ОН A»9 THEN GOTO 100 30 INPUT B 40 IF 8<10 OR B>99 THEN GOTO 2 00 50 INPUT C 60 IF С<100 OR C>999 THEN GOTO 300 70 PRINT АТ 1,1;А; AT 1,8;B;A T 1,15;C 80 STOP 100 PRINT "INPUT A OUT OF RANGE" 110 GOTO 10 200 PRINT "INPUT B OUT OF RANGE" 210 GOTO 30 300 PRINT “INPUT C OUT OF RANGE" 310 GOTO 50 Testing for Zero We can use the NOT routine to check for zeros in a list of numbers. NOT (N) = 0 when N<>0 NOT (0) = 1 Here is a program which sets up a counter C, initialises it, and requests numbers to be input. If a zero is input NOT 0 = 1 and C is incremented by LET C = C + NOT (A(F)). 5 DIM A(19) 10 LET С-й 20 FOR F = 17010 30 INPUT A(F) 35 PRINT A(F);" "; 40 LET C=C+NOT (А(Е)) 50 NEXT F 60 PRINT "THERE ARE";C;"ZEROS" Key in and run the program. Default Values The default value of AND is zero. AND is therefore extremely useful in the addition of logical operations. For example: 60 GOTO (100 AND A= 0) + (200 AND A»0). 277 The default value of OR is 1. OR is thus useful in the multiplication of logical operations. For example, the following program asks you to input any three digits in the range 0 – 9. The computer will generate three digits at random. You win £10, £100 or £1000 depending on how many digits you guess correctly. = REM "“GUESSANLM" 10 DIM ACI) 20 DIM BCS) 20 PRINT “INPUT 3 DIGITS IN TH E RANGE 0-9 ONE АТ A TIME" 40 FOR F=1 TO 3 ФО INFUT ACF) ео PRINT ACF" "3 70 LET E(CF2-2 INT € REND *10) SO NEXT F vo PRINT 100 PRINT БСО?" ";B(2»);" "SBCs à 110 LET Z=(10 OR (Aci) <> Bei) )%(1O ПЕ CACZ) <> B(2)))*(10 OF (ACS) <> Beso) 120 IF Z=1 THEN LET Z=0 130 PRINT “YOU WIN "32 140 INFUT AS 150 IF АФ-"Ү" THEN GOTO 20 160 STOP 278 SECTION S: LISTS AND ARRAYS S1: Dimension The dimension statement DIM is used to reserve storage space for a LIST or ARRAY to contain numbers. DIM A (N) sets up an array A with space for N numbers. A may be any single letter A to Z. The Spectrum will accept both upper and lower case letters, but a(N) will signify the same array as A(N). N may be a number, a numeric variable or an expression. A dimension statement must be declared before the array can be used. This is usually done at the beginning of a program, unless the value of N is to be set equal to an expression or variable which will be calculated later in the program. There may only be one DIM statement on a line for the ZX81. These statements in a program: 10 DIM А(10) 20 DIM B(15) 30 DIM C(30) will reserve storage for a list A containing 10 numbers, a list B containing 15 numbers and a list C containing 30 numbers. The values of each ELEMENT (number) in an array are automatically set (initialised) as zero. Error code 4 (‘out of memory’ on the Spectrum) will be displayed if there is no room for the array, i.e. if N is too large. S2: Index Variable The index variable N is used to locate a member of a list. We use the form A(N) to locate the N'th number of a list A(L), where 1< = N< = L. If N = 5, then A(N) refers to A(5), the fifth number in the list. The program below establishes a four element list, so that: A(1) = 1 A(2) = 4 A(3) = 9 A(4) = 16 and then prints out the second and fourth element. 10 DIM A(4) 20 FOR N=1 TO 4 30 LET A(N) - N*N 40 NEXT N 50 PRINT “SECOND ELEMENT IS ”; A(2) 60 PRINT “FOURTH ELEMENTIS ”; А(4) 279 S3: Lists Many types of problem involve a set of values and it is convenient to store such items in a list. The next program illustrates the idea. We assume a list of the squares of the first 20 integers is required. It is necessary to reserve storage for the twenty numbers (1, 4, 9 etc., up to 400) and this is done in line 20. The loop (lines 30 to 50) puts A(1) = 1, A(2) = 4...A(20) = 400 and it is thus possible to use any item of this list at a later date, using the index variable. Line 60 prints out 4 16 36 and the loop (lines 80 — 100) will print out the complete list of numbers. tO REM "LIST" 20 DIM A(20) 30 FOR N=1 TO 20 40 LET A(N)=N*N SO NEXT N 60 PRINT AC2):" "rACAD;" "j ACE) 70 PRINT 80 FOR N-1 TO 20 90 PRINT ACN) 100 NEXT N S4: Examples of Lists We give below some example programs illustrating the use of lists. 1 Simple allocation of elements in а list. Look at the program. What will be printed out when the program is RUN? Check by entering and running the program. REM *LIST1" DIM A(4) LET A(1)=19 LET A(2)=58 LET A(3)=72 LET А(4)-20 PRINT A(1)*A(3) PRINT PRINT A(3)-A(2) 2 Allocation of values to the elements in a list using a loop and the INPUT statement. The value of the control variable (N) of the loop is used to specify each element of the list in turn. Again, work out the results of the program, then check by keying it in and running it. REM "LIST2" DIM A(4) FOR N-1 TO 4 PRINT "TYPE A(";N;")" 280 50 INPUT A(N) 60 NEXT N 70 PRINT A(1)*A(3) 80 PRINT 99 PRINT A(3)-A(2) 3 АП lists used in a program must be dimensioned, with each dimension statement on a separate line. Hand trace this program and decide what the 10 elements in list B(N) are. Check by entering and running the program. 5 REM "LIST3" 19 DIM А(20) 20 DIM B(10) 30 FOR N-1 TO 20 40 LET A(N)=N*N 50 NEXT N 69 FOR N-1 TO 10 70 LET B(N)-A(2*N)-A(2*N-1) 80 NEXT N 90 FOR N-1 TO 10 109 PRINT B(N) 110 NEXT N 4 А variable may be used in a DIM statement, provided its value Is assigned before the DIM statement is reached. Enter program “LIST4”. Run the program for X = 20. = КЕМ “LISTA” 10 INFUT X ZO DIM A(X) 20 FOR N=1 TO X 40 LET АСМ) = FRR N eO PRINT ACN) 60 NEXT М 5 The program “ОНМ5 LAW?” illustrates the use of lists to store data from a set of electrical circuit experiments. The voltmeter and ammeter readings from each experiment are stored in the lists A(N) and V(N) as they are input. Notice that it is essential to dimension storage space for the derived list of results, R(N), (line 60). The loop (lines 90 to 140) enables the readings to be stored for use in the later loop (lines 180 to 220), which performs the calculation and prints out the results of each experiment, giving the current in amps, the voltage in volts, and the resistance in ohms derived by the formula, R = V/I in line 190. Line 179 initialises a variable T which has each resistance in turn added to it. This enables line 250 to print the average resistance value. 10 REM “OHMS*LAW" 28 PRINT "OHMS LAW RESULTS" 30 PRINT "UP ТО 20 PAIRS OF R EADINGS" 40 DIM А(20) 50 DIM У(20) 60 DIM R(20) 201 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 PRINT "TYPE NUMBER OF SETS OF READINGS" INPUT X FOR N=1 TO X PRINT "TYPE CURRENT IN AMPS" INPUT A(N) PRINT "ТҮРЕ VOLTAGE IN VOLTS" INPUT V(N) NEXT N PRINT "AMPS"; TAB 8; "VOLTS"; TAB 16; "OHMS" PRINT U*#*#*kkkkkkkkkkkkkkkkk ***k LET Т-й FOR N-1 TO X LET R(N) =V(N) /A(N) LET T=T+R (N) PRINT A(N);TAB 8;V(N);TAB 1 6;R (N) NEXT N PRINT U**kkkkkkkkkkkkkkkkkkk ТР PRINT PRINT "AVERAGE RESISTANCE " :Т/Х;" OHMS" Notice that if lines 70 and 80 had come before the DIM statements, we could use DIM A(X), etc. to set the size of the arrays exactly, as in program LIST4 above. 6 А similar type of program is shown below. This shows image positions (V) and magnifications (M) for a convex lens, given the focal length of the lens (F) and the object distance (U). 5 REM "CONVEXLENS" 10 PRINT "THIS PROGRAM SHOWS THE POSITION AND MAGNIFICATION OF ‘THE IMAGE PRODUCED BY A CONVEX LENS" PRINT V e e ee eee eee eee dec dee dee ee e e de e Ax (n DIM U(12) DIM V(12) DIM M(12) PRINT "TYPE FOCAL LENGTH IN CM." INPUT F PRINT "TYPE OBJECT DISTANCE IN CM." FOR N-1 TO 12 INPUT U(N) LET V(N)=U (N) *F/ (U (N)—F) LET M(N)-V (М) /U (N) NEXT N PRINT "U";TAB (8);"V";TAB (22); "M" FOR N-1 TO 12 PRINT U(N);TAB (8);V(N);TAB (22);M(N) NEXT N The screen display will look like this: 282 THIS PROGRAM SHOWS THE POSITION AND MAGNIFICATION OF THE IMAGE PRODUCED BY A CONVEX LENS kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk M U 10 -13,333333 “143353333 20 -40 “2 30 -120 -4 39.555 -3555.5056 -89.887639 40.555 2922.8829 72.072073 50 200 4 60 120 2 70 93.333333 1.3333333 80 80 1 90 72 0.8 100 66.666667 0.66666667 120 60 0.5 S5: String Arrays The DIM statement for string arrays has the form DIM A$ (N,L) where N = number of strings and L = the fixed length of each string. A may be any single letter A to Z, but must NOT be the same as a simple string variable. Each string is set to contain L spaces initially. DIM A$(3,4) will reserve storage space for 3 strings A$(1),A$(2),A$(3), each of length 4, in the string array А8. Each letter of each string can be accessed separately, as with a string variable. A$(2,3) will return the third character of the string A$(2). Substrings may also be allocated by a statement such as A$(2,1 TO 2), which will return the first and second characters of A$(2). For example, if A$(2) = “EFGH' then: A$(2,2 TO 4) = “FGH” The two programs below show these operations. Key them in and run them. Note that spaces may be included as letters, as can any other characters useable in a string. If we have: 20 DIM А%(2.28) 20 LET A$i025z"AEDC Еж G" Шеп АФ(2%40-" " апа АФ(2:35 TO Ез-"Еж G" 1) 5 REM "STRING*ARR1" 10 DIM А5(4,3) 15 PRINT "ТҮРЕ ІМ LETTERS THRE E AT A TIME" 20 FOR N=1 TO 4 30 INPUT AS(N) 40 NEXT N 50 PRINT A$(4,3) ;" ";A$(3,2) 70 PRINT 80 PRINT A$(1);" ";A$(2);" "; А $ (3) 283 2) 10 REM "STR*ARR2" 20 DIM AS(3,4) 30 LET A$(1)="ABCD" 40 LET A$(2)="EFGH" 38 LET AS(3)e"IJEL" 50 PRINT A$(2,4) ;" ";A$(3, 2) 70 PRINT 80 PRINT AS(2,2 TO 4) 90 PRINT 100 PRINT А5(1,3 TO 4) S6: Two Dimensional Arrays A 2-D (two dimensional) numeric array is dimensioned by the statement: DIM A(R,C) where À is any letter, R is the number of Rows and C is the number of Columns. All elements are set as zero. The simple array is one-dimensional, and contains just a linear sequence of items. Arrays can have more than one dimension: 4 6 8 10 12 14 16 18 20 22 24 26 This is a numeric array consisting of £ rows of numbers in 3 columns. Storage would be reserved by the statement: 10 DIM A(4,3). In an array A(R,C) we can access any element, so that in the array above: A(2,1) = 10 A(3,2) = 18 etc. An array of two (or more) dimensions is also known as a MATRIX (plural matrices). The following program establishes an array and prints out two selected elements and then the complete array: “0 REM "ARRAY" 20 DIM А(10:9) 20 FOR R=1 TO 10 39 FOR Cel TO F 40 LET ACR» CO ZEXC 30 NEXT C 60 NEXT Е 70 PRINT Ас10%62»АС2%32 Бо РЕІМТ зо FOR К=1 TO 10 100 FOR C=1 TO 7? 110 PRINT TAB S#Cr ACE C33 120 NEXT С 120 РЕІМТ TAE 4; 140 NEXT К Line 20 allocates the appropriate storage. Nested loops (line 30 — 60) are used to allocate values to the elements in the array. Line 70 prints 284 out two elements in the array. Nested loops (line 90 to 140) print out the complete array. Why is line 130 required? In order to keep track of the elements of an array we need to have a system. In general it is easiest to use R to represent the Rows and C the Columns and to always access the rows before the columns. Note the use of the TAB function to give a clear printout. ] 2 3 2 3 4 6 6 9 8 12 10 15 4 5 6 7 8 9 8 10 12 14 16 18 16 20 24 28 32 36 20 25 30 25 40 45 etc. String arrays can also have more than one dimension. 2-D String arrays are dimensioned by a statement of the form DIM A$(R,C,L) where R is the number of Rows, C is the number of Columns and L is the length of all strings in the array. Try this program: 10 20 30 40 50 60 65 70 80 99 100 110 120 130 REM "2DSTRING" DIM AS (3, 3,53 PRINT "TYPE WORDS 5 LETTERS OR LESS" FOR R-1 TO 3 FOR C=1 TO 3 PRINT АТ 2,0;"ROW ";R;" COL ";C INPUT AS(R,C) NEXT C NEXT R FOR R-1 TO 3 FOR C-1 TO 3 PRINT AT R*4,C*8;AS(R,C) NEXT C NEXT R Key this in and run it. Try some appropriate entries for the rows and columns, as the routine in line 60 gives a cue for which entry is next. This is a useful routine for use with multiple entry INPUT routines, since it is very easy to forget which entry 1s next. One run of this program gave a final screen display like this: 285 TYPE WORDS 5 LETTERS OR LESS ROW 3 COL 3 START 2ND THIRD FOUR FIVE SIXTH SEVEN EIGHT FINAL Note also line 110, where both control variables of the nested loops are used to format the printout using the PRINT AT instruction. 87: Multidimensional Arrays Multidimensional arrays are available for both numbers and strings, although a 3-D string array is rarely something needed in a program! The easiest way of thinking of these arrays is as follows: A (P, R, O) is a 3 dimensional array: page, row, column А (B, P, R, C) is a 4 dimensional array: book, page, row, column. A 5 dimensional array would be a library, on the basis of this analogy. These arrays require DIM statements to reserve the necessary storage. A simple example of a 3 dimensional array (which needs 3 nested loops) is given below. 10 REM "3DLIST" 100 DIM A(3,2,4) 110 FOR P-1 TO 3 120 FOR R=1 TO 2 130 FOR C=1 TO 4 140 LET A(P,R,C)=P*C*R 150 NEXT C 160 NEXT R 170 NEXT P 180 PRINT A(2,1,3) 190 PRINT 200 FOR Р=1 TO 3 210 FOR R=1 TO 2 220 FOR С-1 TO 4 230 PRINT A(P,R,C);" "; 240 NEXT C 245 PRINT 250 NEXT R 255 PRINT 260 NEXT P The similar program below, extended by a dimension, shows a 4 dimensional array printed out in a suitable form. 286 10 REM “4DARRAY" 100 DIM A(2,3,4,5) 110 POR B=) TO 2 126 FOR P=1 TO 3 130 FOR R=1 TO 4 140 FOR Cz] TO 5 150 LET A(B,P,R,C) B*P*R*C 160 NEXT C 170 NEXT R 180 NEXT P 190 NEXT B 200 PRINT А(1,2,3,4):" ";A(2,2,3, 3) 210 PRINT 220 POR В-1 ТО 2 230 FOR Р-1 TO 3 235 PRINT "BOOK";B;"/PAGE";P 240 FOR R=1 TO 4 250 FOR C=1 TO 5 260 PRINT A(B,P,R,C);" “> 270 NEXT C 280 PRINT 290 NEXT R 300 PRINT 310 NEXT P 320 PRINT 330 NEXT B Here's a 3-D string version to try. Input only two letters at a time. Actually it doesn't matter, the computer will ignore any characters in excess of 2, since that 1s the dimensioned length. 5 REM "3D*STR*ARR" 10 DIM A$(3,3,3,2) 20 FOR P-1 TO 3 30 FOR R=1 TO 3 40 FOR C=1 TO 3 50 INPUT AS$(P,R,C) 60 NEXT C 70 NEXT R 80 NEXT P 90 FOR P=1 TO 3 100 FOR R=1 TO 3 110 FOR С-1 TO 3 120 PRINT АТ R*3, (P*10-10)4C*3; AS (P, R,C) 130 NEXT C 140 NEXT R 150 NEXT P Work out how the PRINT AT expressions work. $8: Use of Arrays A simple example of the use of 2-D arrays is shown in the seat booking program below. A small theatre consists of 10 rows of seats with 6 seats in each row. Some seats may already be reserved. These are input when the program is run. When a new booking is made the requested seat, if available, is sold. If the seat is not available a seat in the same row is offered. If no seat in that row is available the customer is asked to choose another row. 287 The sections of the program are as follows: 1 4,2 4.3 Initialise an array to represent the 10 rows of 6 seats (line 30). All elements in this array are 0, and represent unbooked seats. Input seats already booked (lines 40- 130). Input row and seat number of booked seats. If input is @ for the row number, program goes to 2.3. If seat already booked (array element = 1), print message to user. Seat is booked by placing a 1 in the appropriate array element. Program prints prompt, then halts until C is input. Customer request for seat is input (lines 165 ~ 240). Row and seat required are input. If seat already booked (array element = 1), program goes to 4. Seat is booked. Menu is printed to enable user to choose to book another seat, or to view seating plan. If seat booking is requested, program returns to 3.1. If seating plan option is chosen, program goes to 5. Seat unavailable module (lines 300 - 450). Seat unavailable message is printed, then the variable SEATS is set at zero, and the loop checks if at least one seat is free in this row, setting SEATS = 1 if a seat is free (Current Row R, checked for S(R,1) to S(R,6)). If no seats are free in this row (SEATS = 0), program passes to line 440 and prints message, then returns to menu (3.3). If at least one seat is free, the loop at lines 390 to 410 prints out the numbers of the seats free, and the program returns to the menu. View Seat Plan Module (lines 500 — 600). Nested loops are used to display seat plan, row 10 being at the top, as 078 and 175. Copy option is given, to print out seating plan. Menu presented for end of program or return to book seats. Program goes to 3.1, or proceeds to 6. Program ends. Instructions given to restart if required without using RUN and clearing the data stored in the array. 10 КЕМ “THEATRE” 20 REM ##INITIALISE ARRAY ++ 30 DIM 2С(10%442 35 REM **xINSERT SEATS ALREADY жжрГІІКСЕТІ ж 40 FRINT "INFUT SEATS THAT ARS BOOKED, “a "INPUT О TO FINISH" S0 FRINT "ROW?" 60 INPUT F 70 IF R=O THEN GOTO 130 80 PRINT "SEAT?" зо INFUT C 288 100 IF 5(ҒаГ2с1 THEN PRINT "ROW "Е" SEAT "FCs" ALREADY": “BOOK ЕП " 110 LET 5(КзГ2т1 120 GOTO 50 ізо ELS 140 PRINT “INPUT C TÜ PROCEED T Q BOOKING. " 150 INFUT АФ 160 CLS 165 REM w*CUSTOMEF REQUEST FDF3 Xx EAT X% 170 PRINT "ТҮРЕ ROW RERUIRED" 120 INFUT F 170 PRINT "TYPE SEAT NUMBER" 200 INFUT C 210 IF SctR»C)=1 THEN GOTO 300 220 LET S(R»C)=1 230 PRINT “THIS SEAT FREE. NOW E ODKED. " 240 PRINT "ROW "Е" SEAT "С 250 FRINT 260 PRINT “BOOK ANOTHER SEAT (S ӘСЕ VIEW", “SEATING PLAN CFO ТІМЕН T $ OR P" 270 INFUT АФ 280 IF Ag="S" THEN GOTO 170 290 GOTO 500 300 FEM ** SEAT UNAVAILABLE жж 310 PRINT “REQUESTED SEAT NOT A VAILABLE" 320 LET SEATS=0 330 FOR N=1 TO 6 340 IF ЕСЕ» М) =1 THEN GOTO 360 350 LET SEATS=1 360 NEXT N 370 IF SEATS=0 THEN GOTO 440 380 PRINT "SEATS FREE: "; 390 FOR М=1 TO 6 „200 IF S(R|N)=O THEN FRINT М; " 410 NEXT N 420 PRINT "." 430 GOTO 450 440 PRINT "ND SEATS ARE FREE IN ROW “FR 450 GOTO 260 490 REM s* SEATING FLAN жж 500 CLS 510 FOR R=1 TO 10 520 LET X=11-R 530 PRINT TAB 8: "ROW "FX; TAB 1 S40 FOR C=1 TO 6 550 PRINT SCX)? 560 NEXT С 570 FRINT 580 NEXT F 289 590 PRINT +s+s"INPUT C TO COPY ñN Y TO PROCEED” 600 INFT AS 610 IF A$z"C" THEN COPY 620 PRINT аз "INPUT E TO ЕМІЗЕ T О BOOK SEATS." 630 INFUT АФ 640 IF A$-"E" THEN GOTO 670 650 CLS 660 GOTO 170 670 PRINT "PROGRAM STOPPED. US GOTO 170 ТО", "RESTART. " 630 STOP 690 REM ** END PROGRAM жж Screen display, at end of seat plan print routine (the first prompt has been responded to with a user input): ROW 10 000000 ROW 9 000000 ROW 8 000000 ROW 7 000000 ROW 6 000000 ROW 5 000000 ROW 4 000100 ROW 3 100000 RW. 2 дылы ROW 1 000000 INPUT C TO COPY,ANY TO PROCEED INPUT E TO END,S TO BOOK SEATS. The variables used in the theatre booking program are as follows: S(10,6) SEATS “THEATRE” - DATA TABLE Array to store 10 rows of 6 seats (value 1 when seat booked, 0 when free). Current Row of array in processing. Current Seat number in processing. User Input string for menu choices. Marker used to indicate whether seats are free in current row. Set to 0 when no seats free, 1 when seats available. Loop variable. Value used in processing inside loops to check seat availability, and print seat numbers. Loop variable used to print seat plan. Note this is the same name as the variable for Rows above. This name may be used in two different ways in this program because the value of the simple variable R is re-initialised by the input at line 17@ on return to the seat selection routine. Variable used for reverse printing of seating rows. 290 C Loop variable for seats in seat plan printing. As with R above, re-initialised as simple variable on return to seat selection routine. Note that the use of variables in two ways, as with R and C in this program is only possible if the simple variables will be re-initialised every time they are used, otherwise problems can arise. A loop variable erases a simple variable of the same name. It would be better practice to use different names for the two types of variables. 291 SECTION T: SORTING SEARCHING AND STORING ARRAYS T1: Searching and Sorting Searching a list of numbers (or strings) for specified values can obviously be done much more efficiently if the numbers (or strings) are sorted according to some specified order, commonly alphabetical order or ascending numerical order. In electronic data processing groups of records (files) can be handled more efficiently if the records are pre- sorted into a specified order (e.g. by merging transaction files into a master file). Various techniques have been developed to sort data and several of the simpler methods are illustrated in this section together with two simple methods of searching lists. There is a considerable difference in the efficiency of the various sorting techniques depending on the type and volume of data to be sorted. A technique which is good for a random list of numbers may not be appropriate for a list in which only one number is out of sequence. For random lists the Quick Sort and Shell Sort techniques are very much faster than a Bubble Sort. Deciding on which is the most suitable method is largely a matter of experience and you should experiment using the different techniques for equivalent sets of numbers, timing the sort procedures. Many sorting algorithms exist, and we will first deal with the simplest. The BUBBLE SORT is used for sorting numbers (or strings with appropriate alterations) into ascending or descending order. The principle of the bubble sort is to compare adjacent numbers and change positions if they are in the incorrect order. This is done for elements 1 and 2, then 2 and 3, 3 and 4..Х-1 to X at the end of which the highest number is in the Xth position. This is repeated (and the next highest number bubbles up to the X ~ 1th position) and repeated again, until the ordering is complete. The following program is a bubble sort to put numbers into ascending order. The sorting routine itself 1s in lines 130 to 225. 10 REM "BUBBLE" 20 PRINT "TYPE NUMBER OF ITEMS TO BE SORTED" 25 PRINT "MAXIMUM NUMBER 50" 30 INPUT X 35 IF Х>50 THEN GOTO 25 40 DIM A(50) 60 PRINT "TYPE NUMBERS ONE AT A TIME" 75 LPRINT "UNSORTED LIST" 80 FOR №] TO X 90 INPUT Z 100 LET A(N)-Z 110 LPRINT A(N) ;" "; 120 NEXT N 125 LPRINT 292 130 REM **SORTING ROUTINE**** 140 FOR N-1 TO X-1 150 FOR M-1 TO X-N 160 LET C=A(M) 170 LET D=A (M+1) 180 IF C<=D THEN GOTO 210 190 LET A(M)=D 200 LET A(M+1)=C 210 NEXT М 220 МЕХТ М 225 REM ******gND SORT****** 230 LPRINT "SORTED LIST" 249 FOR N=1 TO X 250 LPRINT A(N);" "; 260 NEXT N Sample printout: UNSORTED LIST 129 267 56 41 69 43 99 90 4 8 SORTED LIST 4 8 41 43 56 69 90 99 129 267 То illustrate (һе operation of the program, we'll take the first four of these numbers and see how the program sorts them: Bubble sort for 4 numbers A(1), A(2), А(3), A(4) inputas L29, 26/, 530, 41 Procedure: (1) Go through the list comparing successive number pairs. For example: A(1) and A(2), then A(2) and A(3). If А(1)>А(2) then they are swapped so that A(2) becomes A(1) and A(1) becomes A(2). If A(1) =A$(N) THEN GOTO 209 170 LET Т5-А5(М-1) 180 LET AS(N+1) =A$(N) 190 LET AS(N) -T$ 200 NEXT N 210 NEXT M 220 PRINT 230 PRINT "SORTED LIST" 240 FOR N=1 TO X 250 PRINT AS(N), 260 NEXT N Some care must be exercised if the above sort is to be used on numbers entered as strings. The example given below shows that it will work frovided one ensures that all numbers entered have the same number of figures. (1 Incorrect use: HOW MANY STRINGS MAXIMUM 10 CHARACTERS UNSORTED LIST 129 99 543 6 456 897 567 21 345 45 295 SORTED LIST 123 21 345 45 456 543 567 6 897 99 (п) Correct use: HOW MANY STRINGS MAXIMUM 10 CHARACTERS UNSORTED LIST 123 099 543 006 456 897 567 021 345 045 SORTED LIST 006 021 045 099 123 345 456 543 567 897 Т4: Insertion Sort This is another type of sort which is more efficient than the Bubble Sort and is also the basis of an even faster sort called a Shell Sort. Speed is a prime consideration when sorting large amounts of data. Consider the list of numbers: 3 2 5 4 1 We start with the first entry іп the list. Then we take the second item, compare the two, and swap if necessary. Then the second is compared with the third, a swap performed if required, and 7f a swap was made the first and second are compared again, and swapped if necessary. Then the third item is compared with the fourth, and so on. The list above will be sorted like this: 296 Swap 3 2 у 4 2 3 i23 3 9 777773 Swap 5 4 у + 4 5 9 Swap 5 1 + + 1 5 Бе «> Swap 4 1 у + 1 4 es: Swap 3 1 + 4 1 3 — a Swap 2 1 V 4 1 2 Consider the list A(1), A(2) . . . A(X). To insert item A(I+ 1) in the correct position: Let T = A(I+ 1), then if T> = А(Т) no swap is necessary and no further comparisons аге required. if T= ACI) THEN GOTO 270 LET AtCJd+1)=A¢.)) LET J=J-14 IF J >= 1 THEN GOTO 220 LET ACJ+1)=T NEXT I REM XxEND SORT MODULE жж 555525555522 22555 РЕІМТ PRINT “SORTED LIST" ЕСЕ N=} TŪ X PRINT ACN)" "; NEXT N FEM xENIS x A trace of the program, using our example list again, can be shown like this: 298 T5: Shell Sort The procedure in this sort is to precede an insertion sort by a process which, if we consider a list of numbers to be placed in ascending order left to right, will move low values to the left and high values to the right more quickly. Consider an 8 element list A(8), holding the values: 74, 32, 59, 46, 26, 9, 62, 42. The sort proceeds in the following stages: 1) Divide the 8 by 2 and compare elements 4 positions apart in the list, swapping if necessary: A(1) A (2) A (3) А (4) A(5) А (6) А(7) А (8) 74 32 59 46 26 9 62 42 Сотраге А(1) апа А(5) Swap A(2) and A(6) Swap A(3) and A(7) In order - leave A(4) and A(8) Swap New list: 26 9 59 42 74 32 62 46 2) Divide the 4 by 2 and compare the elements 2 positions apart in the list and swap if necessary: 26 59 g me 59 74 42 (SWAP) 32 74 (SWAP) 62 42 32 46 New list: 26 9 59 32 62 42 74 46 3) Divide 2 by 2 and compare elements 1 apart in the list, which is using the equivalent of an insertion sort to give the final order: 9 26 32 42 46 39 62 74 The steps we make in the program are as follows: a) Select an integer S (number of positions apart from comparison). This is usually taken as INT (N/2) where 299 b) c) N = number of items in the list. Sort the lists of items Š positions apart, by comparing and swapping if necessary. If S<1 then stop, since the list is sorted. If S>=1 then pick a new value of S (usually INT(S/2)), and repeat steps b) to d) as often as necessary. 5 REM "SHELL" 10 PRINT "HOW MANY NUMBERS?" 20 INPUT X 30 DIM A(X) 50 PRINT "TYPE NUMBERS" 60 FOR N-1 TO X 70 INPUT A(N) 80 NEXT N 90 PRINT 100 PRINT "UNSORTED LIST" 110 FOR N-1 TO X 120 PRINT A(N); " "; 130 NEXT N 140 PRINT 198 REM **SORTING ROUTINE** 200 LET S-X 210 LET S=INT (S/2) 220 IF S«1 THEN GOTO 400 230 FOR K-1 TO S 240 FOR I-K TO X-S STEP K 250 LET J-I 260 LET T=A(I+S) 270 IF T»-A(J) THEN GOTO 312 280 LET A(J+S) -A(J) 290 LET J=J-S 300 IF J»-1 THEN GOTO 270 310 LET A(J+S) =T 320 NEXT I 330 NEXT K 340 GOTO 210 350 REM **END OF SORT** 400 PRINT 410 PRINT "SORTED LIST" 420 FOR N-1 TO X 430 PRINT A(N) ;" "; 440 NEXT N 450 REM **END** 300 Hand trace of Shell Sort Consider the 8 element list 74, 32, 59, 46, 26, 9, 62, 42. X =8. 310 T = 1 2 3 4 2 4 3 2 9 )=74 A(6)=32 A(8)=46 i A(1)=26 A(2)=9 A(7)=62 A(4) 62 42 32 46 62 4 At this stage (1) the list is 26, 9, 59, 42, 74, 32, 62, 46. 210 220 230 240 250 260 S | 2 S=1 Қ = 1 2 [= J 2 3 4 5 6 2 4 6 J = 1 2 3 4 5 6 2 4 6 T = 59 42 74 62 46 32 42 46 A(7)=74 A(5)=62 A(8)=46 A(4)=32 A(6)=32 А(8)-46 At this stage (2) the list is 26, 9, 59, 32, 62, 42, 74, 46. The final stage is the comparison of neighbouring elements using the insertion sort technique, to which the Shell Sort routine is equivalent when S = 1. This is perhaps more easily seen if we consider the trace below of the operation of the Shell Sort program on a simple 5-item list, in which only two passes need to be made. 301 I = 3 r = 2 I = 2 J = 3 J=2 J = 2 Start T=A (5) T=A (4) T=A (5) Pass 2 A(2)=4 А(3)-1 А(4)-3 А(5)-5 Тһе two methods of tracing а program illustrated here should show you the method by which a systematic analysis can be made of the changing values of variables in a program as processing proceeds. This is a procedure you should put to use when designing a program (i.e. in checking that the algorithm will work as intended) and when checking the operation of other people’s programs that you wish to analyse. The procedure is also a great help in debugging a program. Break points inserted into the program (STOP commands), after which you can print the values of variables by direct commands, or PRINT statements, inserted as appropriate to print the values of variables at each step in the program, will enable you to check that the values occurring in the program are the same as the ones your trace diagram shows. You can even LPRINT values to get a printout, if many passes are to be made in the program. T6: Quick Sort This provides a fast sorting technique which works by subdividing the list into two sub-lists and then subdividing the sub-lists. The principle of the Quick Sort is as follows: consider a list A(X) containing X numbers. We assume as an example that X = 8 and the numbers are as shown below. The following steps are carried out: 302 1) 2) 3) 1) Initialise two pointers, I and J, at opposite ends of the list. Let X(I) be the reference number. In our example, this is 63. I J 63 27 43 96 72 31 82 43 Compare the two numbers indicated by the pointers and swap if necessary. I J 43 27 43 96 72 31 82 63 Move the pointer opposite the reference number one place towards it. | J 43 27 43 96 72 31 82 63 Repeat steps 2) and 3) until I= J. I J 43 27 43 96 72 31 82 63 ! J 45 27 43 96 72 31 82 63 I J 43 27 43 63 72 31 82 96 ' J 43 27 43 63 72 31 82 96 I J 43 27 43 31 72 63 82 96 I 43 27 43 31 63 72 82 96 When this stage has been reached the list has been split into two sub-lists. The reference number is now in its correct position in the list, and the sub-lists are the numbers to the left and right of this position. 303 5) One of the lists is stored for future sorting (see below) and the other is taken through steps 1 to 4 above. [43 27 43 31] 63 [72 82 96] mss, ee ee continue with store sub-list sub-list in correct position I J 43 27 43 31 I J 31 27 43 43 г J 31 27 43 43 New Sub-list [31 27 43) 31 Zi 43 in correct position 31 27 27 31 43 in correct position 6) This process is repeated, in each case storing a sub-list where necessary, and finally going back and sorting all stored sub-lists so that eventually each number is in the correct position. The left-hand and right-hand numbers of a list are denoted by sub- scripts L and R respectively. The pointer positions are denoted by I and J and a flag S is set to indicate the pointer at the reference number, so that: S = 1 if reference number at pointer I S= – 1 if reference number at pointer J If at the end of step 4 the reference number is at I (as in our example) then the list has been split into: reference sub-list sub-list Es. uni l= I Пі, ... > X) The right-hand list is remembered by setting up a stack, using an array S (P,2) with P initially set to zero. As each sub-list is stored, we make: P=P+1 S(P,1)2I + landS(P,2)=R 304 The array S is initially dimensioned as S(X,2) for a list with X elements. P indicates the number of the sub-lists; S(P,1) the left-hand element and S(P,2) the right-hand element of the sub-list. In the example given, at step 5 we will have the first sub-list generated stored by setting: P = 1, S(P,1) = 6 and S(P,2) = 8 Thus each list to be stored is placed in sequence into the array, this process being known as PUSHing on to the STACK. When the sub-list that the program continues with finally has only one number we must return to sort the stored lists. We retrieve a stored sub-list (POP a list out of the STACK) by letting: L=S(P,1),R=S(P,2)andP=P-1 and continuing until all the lists are sorted. Program Listing = КЕМ "QUICK" 10 PRINT "HOW MANY NUMBERS?" 20 INFI'T X 20 DIM A(X) 40 DIM 5(Х,2) SO PRINT :*"INFUT NUMBERS" во ЕКПЕ N=1 TO X 70 INFUT АСМ) Z0 NEXT М 90 PRINT 100 PRINT “UNSORTED LIST" 110 FOR N=i TO X 120 FRINT ACN" "3 130 NEXT М 140 PRINT LEQ REM же Ж ЖЖ ыы 3 + жж SORTING ROUTINE жж 190 LET P=0 200 LET L= 210 LET R= Жә LET. Lim 230 LET J= 240 LET $= 2 СІ = ACJ) THEN GOTO = 270 LET ACD =ACN 280 LET ACJ3I=T 290 LET 5з-5 200 IF S=1 THEN LET I=I+1 ӘТО IP Sel THEN LET Ue Jed 320 IF I= R THEN GOTO 270 340 LET F=F +! 350 LET S(P+1) 360 LET 5Р2) 370 LET RzI-1 1 i+ Е 305 280 IF L«R THEN GOTO 220 290 IF Р=0 THEN GOTO 420 400 LET L=icFs1) 410 LET Е->2(Р.2) 420 LET Ғ-Ғ-1 4260 GoTo 290 440 REM w* END OF SORT ++ 3C 3c 3C 3€ 3C 3€ 363€ ЖЗ 450 PRINT 4&0 PRINT “SORTED LIST" 470 FOR N-1 TO X 420 PRINT ACNO:" "; 490 NEXT N 200 REM жж ЕМПРЕПС жж Lines 190 - 230 initialise P, and set values for L, R and the pointers I and J. Line 240 sets the flag which indicates the position of the reference pointer (S = - 1). Lines 250 — 290 make the interchange of A(I) and A(J) if necessary and reset the flag. Lines 300 — 320 move whichever of I and J is to be moved, according to how the flag is set. Line 330 checks if I is at the end of the list, bypassing the sub-list storage routine. Lines 340 — 360 ‘push’ sub-lists on to the stack. Lines 370 and 380 check if the sub-list has more than one element, sending control back to line 220 if it has. Line 390 sends control to the print routine if no sub-lists are stored. Lines 400 — 420 ‘pop’ sub-lists out of the stack. Line 430 starts the sort routine for the ‘popped’ sub-list. T7: Index Sort When data records or files contain several items (‘fields’) of information we often need to sort them according to one particular item. An index sort routine will enable us to do this. For example, we may have a series of records each containing a reference number, name, sex, age, home town and occupation: 10 SMITH MALE 21 OXFORD BUTCHER 20 JONES FEMALE 32 ENFIELD GROCER Each record contains six fields. We might wish to sort these records alphabetically by name (field 2) or numerically by age (field 4). A sort of the type presented here enables this to be done for any of the fields. Since it uses string arrays to hold records and performs an alphabetical sort it is necessary for all numerical items in any field to contain the same number of digits. We must hence use 010, 020, 100, 200 and not 306 10, 20, 100, 200, using leading zeros to maintain the value, but giving the same number of digits. The procedure is as follows: 1. Set up an array N$ (N,L,C) containing N records, each of L fields with a maximum of C characters in any string. For example, we might use an array N$ (10,5,20), to represent 10 records, each with 5 fields, which can each contain up to 20 characters. Decide on the key field (i.e. the field you wish to sort) — say the Jth field. We must then set up an array K$(N,C) to store it, and let K$ (R) = N$ (R,]) for the number of records (FOR R = 1 to N) so that the list K$ (N,C) will then contain the items we wish to arrange in order. Sort the key field into ascending order. This is done in the subroutine starting at line 900 by counting how many times each element in the array K$ (N,C) is >= the other elements (including itself). ‘This sort uses a numerical array X(N) to store the result of this count (P) for each element, by setting X(P) to equal N, when K$(N) is the item being checked. We first set P = 1 (since each item is equal to itself) and then check through the other items of K$ (lines 920 to 970), making the count by letting P = P + 1 when the element is >= another element. If the elements are equal, the original order in N$ is kept (line 960): (i.e. test first element of K$ and set X(P) = 1, reset P, test second element of K$ and set X(P) = 2, etc.) For example, with 10, 30, 20, 40 as our K$ list, the array X(4) would hold the values: 10 X(1)- K$ (1) 30 X(3)= K$ (2) 20 X(2)-KS$ (3) 40 X(4)- К (4) Printing out K$ (X(1)) to K$ (X(4)) in order will give the sorted order of K$ elements. The array N$ (X (N), L, C) will now consist of the records sorted in the appropriate order, according to the field chosen, and is printed out using the loop variables R and I to access N$ (X(R), I) in lines 290 to 340. Program Listing 5 КЕМ "INDEX" 10 PRINT “SORTING RECORDS" 20 FEINT »» "ТҮРЕ MAXIMUM NUMBE К OF CHARACTERS IN ANY ITEM" 307 30 INFUT C 40 PRINT 33 "HOW MANY RECORDS?" SO INFUT М ео PRINT +, “HOW MANY ITEMS IN EACH RECORD?" 70 PRINT Өө МЕЛТ L SE REN 333 3 Хы HH ##INITIALISE $ ARRAYS ++ ЭО DIM ММУ Li; U) 100 DIM K$6N3:0CO 110 DIM ХОМ) 120 REM 3333 5 ЖЕ EERE ЖЖІМРИТ RECORDS жж 130 FOF Р-і ТОМ 140 PRINT “ТҮРЕ "#15" ITEMS FOR RECORD "sk 20 FOR Ісі TO L 160 INFUT N$iE:I2 170 NEXT I 120 NEXT F 190 PRINT 200 PRINT "WHICH ITEM IS SORTIN G KEY?" 210 INPLT J 220 FOR Есі TON 220 LET EKSCRI=NSCRy J) 240 NEXT Е 750 GOSE VOO 260 PRINT 270 FRINT “SORTED RECORDS ARE: " 220 PRINT 290 FOR Е=1 ТОМ 200 FOR Ісі Tü L 310 PRINT N$CXORD IOS" "5 320 NEXT I 220 PRINT 240 NEXT Е 220 PRINT 260 PRINT "DO YOU WISH TO CONTI ММЕЗСҮ/М9" 97/0 ¿NPUT Үз 280 IF Y$-"Y" THEN GOTO 200 390 STOP 400 REM *##*#FROGRAM END жж 3C 3t 3€ 3€ 3€ € € 3E € 9€ 9E 3€ 9€ C 3E 3E 3€ 3€ 9€ 3C 3€ 903€ ООо REM J39)t3 3 9 3 9€ X 9 9€ 963€ 9€ 9€ 96 3€ 3€ 9E 9E Ж ##S0R TING SUBROUTINE «3 700 FOR Асі TON S10 LET Pel 720 FOR Е=1 TO N 930 IF K$(ñ3:K$(E) THEN LET FF 940 IF КФА) =КФСЕ) THEN GOTO 96 750 GOTO 970 760 IF АРЕ THEN LET Р=Р+1 970 NEXT E 950 LET ХҰРотА 990 МЕХТ А 308 1000 RETURN 1010 REM ** ENDSUE ++ ЗЕ ЗЕ ЗЕ HEHE ХАЖ For example, if we input a storage array of £ records with 3 fields, maximum 6 characters in any item, and use as input data: SMITH, 460, OXFORD JONES, 080 LEEDS BROWN, 730, YORK WHITE, 095, BATH Results are as follows: (1) Using field 1 as key Sorted records are: BROWN 730 YORK JONES 080 LEEDS SMITH 460 OXFORD WHITE 095 BATH (п) Using freld 2 as key Sorted records are: JONES 080 ^ LEEDS WHITE 095 BATH SMITH 460 OXFORD BROWN 730 YORK (ш) Using field 3 as key Sorted records are: WHITE 095 BATH JONES 080 LEEDS SMITH 460 OXFORD BROWN 730 YORK T8: Linear Search The most straightforward way of looking for a particular number in a list of unsorted numbers is to examine the list one by one in each case comparing with the *wanted' number. In this program a set of random numbers is created between 100 and 199 and it is arranged so that there is only a single occurrence of each 309 number. This is in lines 40-60. The list is printed out in lines 70-110. The search routine is then carried out in lines 200 — 300. Clearly a number near the beginning of the list is found quickly but one at the end rather slowly. For a 5@ element list the average number of searches will be 25. 5 REM "SEARCHI" 10 DIM A(100) 15 PRINT "TYPE NUMBER <100" 20 INPUT N 30 IF N»100 THEN GOTO 15 40 FOR M=] TO N 50 LET A(M)=INT (1ØØ*RND) +100 52 FOR R=1 ТОМ-1 54 IF A(M)=A(R) THEN GOTO 50 56 NEXT R 60 NEXT М 70 PRINT "UNSORTED LIST" 80 FOR M=1 TO N 90 PRINT A(M);" "; 100 NEXT M 110 PRINT 200 REM **LINEAR SEARCH** 210 PRINT "TYPE NUMBER BETWEEN" 220 PRINT "100 AND 199" 230 INPUT X 249 FOR I-1 TO М 250 IF X=A(I) THEN GOTO 300 260 NEXT I 270 PRINT "NUMBER NOT IN LIST" 280 PRINT "AFTER ";N;" SEARCHES" 290 GOTO 400 300 PRINT "NUMBER ";X;" AFTER "; I;" SEARCHES" 400 REM **END** T9: Binary Search This is a much faster search technique than the linear search but can only be used for a list that has already been put in order. In many applications you will be dealing with an ordered list and under such circumstances this is the appropriate method to use. In the program the binary search technique is in lines 500 to 600. The basic idea is to compare the wanted number with the middle item of the ordered list. The wanted item is then either smaller (in which case we know it is in the first half of the list) or larger (in which case it is in the second half of the list) than the middle item, unless it is equal to it-in which case we have completed our search. The process is repeated, in each case halving the list. Consider a search for 30 in the following list: l 2 4 6 8 10 12 14 16 18 20 24 28 30 36 We first choose 14 (middle). 310 Our list is now: 16 18 20 24 28 30 56 and we choose 24 (middle). Our list 1s now: 28 30 36 We select 30 (middle). Thus we have found the number in three searches (compared with fourteen using the linear search). In the program the following sections occur: (1) Setting up initial unordered list and printing out (lines 10 — 150). (ii) Sorting this list into order and printing it out (lines 200 — 330). (ш) Binary search with printout (lines 500 — 680). 5 REM "SEARCH2" 10 DIM А(50) 20 PRINT "TYPE NUMBER <50" 30 INPUT N 40 IF М>50 THEN GOTO 20 50 FOR M-1 TO N 60 LET A(M)=INT (100*RND)+100 70 FOR R=1l TO M-1 80 IF A(M)-A(R) THEN GOTO 60 99 NEXT R 100 NEXT M 110 PRINT "UNSORTED LIST" 120 FOR M-1 ТОМ 130 PRINT A(M);" "; 140 NEXT M 150 PRINT 200 REM **{NSERTION SORT** 210 FOR Ізі ТО N-1 220 LET J-I 230 LET T=A(I+1) 240 IF T»-A(J) THEN GOTO 280 250 LET A(J+1)=A(J) 260 LET J=J-1 270 LET J»-1 THEN GOTO 240 280 LET A(J+1)=T 290 NEXT I 295 REM ***ENDSORT*** 300 PRINT "SORTED LIST" 310 FOR M-1 TO N 320 PRINT A(M);" "; 330 NEXT M 340 PRINT 350 PRINT "TYPE NUMBER REQUIRED" 360 PRINT "BETWEEN 100 AND 199" 370 PRINT "TO FINISH TYPE 999" 380 INPUT X 390 IF X-999 THEN GOTO 709 400 PRINT 311 Results: 410 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 PRINT "SEARCH ";N;" ITEM LI ST" REM **BINARY SEARCH** LET L=l LET H=N LET С-О LET M=INT ((H+L) /2) LET С=С+1 IF X=A(M) THEN GOTO 630 IF L>=H THEN GOTO 660 IF X>A(M) THEN GOTO 610 LET Н-М-1 GOTO 540 LET L=M+1 GOTO 540 PRINT "NUMBER FOUND ";X PRINT "AFTER ";C;" SEARCHES" GOTO 350 PRINT "NUMBER NOT FOUND" PRINT "AFTER ";C;" SEARCHES" GOTO 350 REM **END SEARCH** REM **END** TYPE NUMBER «50 UNSORTED LIST 117 118 101 189 188 197 172 106 130 181 100 165 155 167 199 138 113 143 154 194 106 107 111 113 128 130 131 133 148 150 Loo 154 165 167 168 172 144 128 150 107 168 160 186 190 131 142 SORTED LIST 100 101 119 122 143 144 160 163 186 188 189 190 194 197 TYPE NUMBER REQUIRED BETWEEN 100 AND 199 LO FINISH ТҮРЕ 999 SEARCH 40 ITEM LIST NUMBER FOUND 198 AFTER 5 SEARCHES T10: Storing a List We can store data in an array for use in a program via INPUT loops when there is more data to be inserted than we care to put directly in the program using LET instructions. There are programs in the text that use this technique (e.g. “ЕГЕМЕМТ”). To illustrate the 214 111 127 175 122 119 117 138 155 175 198 198 148 133 163 153 118 142 157 181 199 technique, here is a simple example that doesn't require you to INPU T anything. Key in and run the first program to create A(N) and fill it with random numbers. Edit the program, replacing the original lines with those of the second program. SAVE this program. LOAD it back in. If we used RUN it would clear all the variables, and wipe out the array we have stored. Program execution must be started with a GOTO statement, in this case GOTO 10. The array will then print out. 10 DIM A(40) 20 FOR N=1 TO 40 30 LET A(N)=INT (100*RND)+100 40 NEXT М 10 REM "SAVED*ARRAY" 20 REM **EXECUTE PROGRAM** 30 REM **USING GOTO 10%% 40 PRINT "LIST OF RANDOM NUMBERS" 50 PRINT "BETWEEN 100 AND 199" 60 FOR N-1 TO 40 70 PRINT A(N) 80 NEXT N So this 1s the general procedure: (1) Write an array creation program and run it, i.e. A(N) created and data inserted. (2) Edit out lines and put in additional lines as required. (3) SAVE the final program. (4) LOAD program and execute using a GOTO statement. To avoid the possibility of the user entering RUN, we can use a structure which automatically initiates the program on loading. The program below for the ZX81 also illustrates the fact that one may use a string variable as a program name. Lines 10 to 80 create array and have the input routine. These lines could be edited out as soon as the data was input, or left in to enable (through the use of RUN) a different set of data to be input. Line 90 onwards are the program to use the stored data. Line 9010 requests a string input to be used as the program name. 9020 gets the string, and 9030 and 9040 give you the chance to write it down before you forget. 9050 waits for a key to be pressed, and 9070 saves the program and its variables. One of these variables stores the line the computer had got to in the program, and when loaded back it starts where it left off (9070) and goes to line 90 automatically. 10 REM **AUTO-RUN ROUTINE** 20 REM AUTOMATIC RUN WILL PRESERVE VARIABLES 30 REM AVOID STATEMENTS OR EDIT THEM OUT. 40 REM ***DIMENSION/INPUT, ТО STORE VARIABLES *** 50 DIM А(20) 60 FOR F-1 TO 20 313 70 INPUT А (Е) 80 NEXT F 90 PRINT "PROGRAM TO USE DATA" 100 FOR F=20 ТО 1 STEP -1 110 PRINT A(F) 120 NEXT F 130 REM ...... MORE PROGRAM 140 REM ....... 8990 REM **SAVE AND AUTO-RUN** 9000 CLS 9010 PRINT "INPUT PROGRAM NAME" 9020 INPUT AS 9030 PRINT "PROGRAM NAME:";A$ 9949 PRINT "READY TO SAVE.NOTE P ROGRAM NAME.PRESS A KEY TO SAVE PROGRAM","AFTER SETTI NG CASSETTE TO RECORD*****" 9050 IF INKEYS="" THEN GOTO 9050 9060 CLS 9070 SAVE AŠ 9075 REM **GOTO LINE AFTER DIM/ INPUT ROUTINE IF NOT EDITED OUT kk 9080 GOTO 90 The Spectrum has an automatic message and built in wait-for-key- press routine. It also has an automatic run-after-LOAD facility. If a line is entered in a program of the form: 9000 SAVE ‘‘program’’ LINE 200 and the program is saved with a GOTO 9000, the program will start running after loading by going to the line stated (200 in the example). For the Spectrum, this program needs modifying by deleting lines 9070, 9075, 9080, changing 9040 to read PRINT*'NOTE PROGRAM МАМЕ”, 9050 to PAUSE 0, and 9060 to SAVE A$ LINE 90. T11: Storing a String Array The ZX81 program PRETTY draws a picture on the screen (slowly!) which is stored in the array A$, dimensioned in line 100. If this program is run the array A$ is created, and the screen display stored, character cell by character cell, in A$. The lines in the program can be edited out so that finally we have a program like PRETTY2. This may be SAVEd and includes the created array A$. To execute the program PRETTY2 after loading we must use GOTO 5, to avoid the use of RUN, which clears all arrays (and hence A$) before execution starts. 5 REM "PRETTY" 10 FOR J-1 TO 19 20 FOR N=ø TO J*12 30 PLOT 32-27%2%5ІМ (N/(J*6)*PI), 224J*COS (N/(J*6)*PI) 40 NEXT М 50 NEXT J 314 100 DIM A$(704) 110 FOR I=0 TO 21 120 FOR Ј=1 TO 32 130 LET A$(J+32*I)=CHR$ PEEK (PEEK 163964256*PEEK 16397-4J-433*I) 140 NEXT J 150 NEXT I 5 REM "PRETTY2" 10 PRINT A$ Notice that we have stored the screen display in the array. Check you understand the process of PEEKing the display file. The Spectrum stores a screen display using a special form of SAVE. This has the form: SAVE “РКЕТТҮ” SCREENS, where PRETTY can be any name. This is loaded back using LOAD “РКЕТТҮ” SCREENS. Try this procedure on your Spectrum. The program above can be revised for the Spectrum. Enter just the following lines: 10 FOR J=1 TO 40 STEP 4 20 FOR N - 0 TO J*12 STEP 4 30 PLOT 125 + J*2*SIN(N/(J*6)* PD,88 + J'COS(N/(J*6)*PI) 40 NEXT N 50 NEXT J Use SCREENS to save the picture as above. To continue with screen displays, the Spectrum can store a screenful of characters in much the same way as the ZX81 program above, using SCREENS to access each character in turn, placing them in sequence in array A$(704). A screenful of characters is generated at random, using the single characters from the Spectrum character set, placing these along each line. The double loop (lines 60 to 100) uses SCREENS (F,N) to check each character along each line, placing it in the array A$. = DIM 4$(7042 10 FOR F=0 TO 21 20 FOR NzO TO 31 30 PRINT АТ F:N? CHES (32+ ЕМІ #97) 40 NEXT N SO NEXT F ео FOR Ғ-о Tü 21 70 FOR М-о ТО 31 SO (ЕТ AS(N+14+32#F3=SCREENS СЕ» № 70 NEXT N 100 NEXT F Now edit out all the lines, replacing 5 with 5 PRINT A$, and RUN the program using GOTO 5. 315 The same program for the ZX81 needs to use PEEK to access the display file, just as in “РКЕТТҮ”. Replace lines 5 to 50 in “PRETTY” with the following, to print a random set of ZX81 characters on the screen: 5 КЕМ "SCREENFULL " 10 FOR F=1 TO 704 20 PRINT СНЕФ INT ( REND #54); 30 NEXT F The same principle holds good for any string array or numeric array. Once the program has been run and the data inserted into the array, the data is safe as long as RUN is not used again, and can be accessed as required. The ELEMENT program treated in Unit W3 uses this procedure to store data required in the program. Exercise Write the appropriate array creation program for the following program: 10 REM "SAVEI10" 20 REM **THIS PROGRAM MUST BE** 30 REM **EXECUTED USING GOTO10** 40 PRINT “MONTHS OF THE YEAR" 50 FOR N-1 TO 12 60 PRINT M$ (N) 70 NEXT N T12: Storing Data in Strings Strings can be used to store data, which may be accessed using the string-handling instructions. The data can also be re-assigned, or new values inserted. Numbers may be used, the STR$ and VAL instructions enabling conversion from numbers to strings and vice versa. The first example has the data stored in A$. The names of the months are all three letters long, and can thus be accessed using the simple numeric calculation of line 70. 10 REM STRING DATA STORE 20 REM *AS HAS DATA* 30 LET A$="JANFEBMARAPRMAYJUNJ ULAUGSEPOCTNOVDEC" 40 REM *DATA INPUT* 50 PRINT "INPUT MONTH(1 TO 12) н 60 INPUT MONTH 70 PRINT "MONTH ";MONTH;" IS " ;AS(MONTH*3-2 TO MONTH*3) 316 The next program has the full names of the months, with varying lengths. Full stops are used to make the principle clear, but spaces between the months would be used in a practical program. (As it is, a full stop is printed after the month, rather than the useful space.) The program stops the search after the required month has been found (line 100), but is a little slow on the ZX81 unless FAST is used (line 65). 10 REM STRING DATA STORE 20 REM *AS HAS DATA* 25 REM **USE SPACES,NOT FULL S TOPS IN REAL PROGRAM** 30 LET AS=".JANUARY. FEBRUARY.M ARCH. APRIL.MAY.JUNE. JULY. AU GUST. SEPTEMBER. OCTOBER. NOVE MBER. DECEMBER," 40 REM *DATA INPUT* 50 PRINT "INPUT MONTH(1 TO 12) " 60 INPUT MONTH 65 FAST 70 LET P=0 80 LET A-1 90 IF AS(A)="," THEN LET Р=Р+1 100 IF P=MONTH+1 THEN GOTO 140 110 IF P=MONTH THEN PRINT AS (А+ 1); 150 PRINT "IS THE MONTH INPUT" Spectrum users should, of course, delete the FAST and SLOW instructions, lines 65 and 140. The next program uses a string to store numeric data. The numbers are input, and placed in the string as the STR$ string plus ‘‘*’’, which is used as an indicator. The data is retrieved by using the subroutine (at line 1000) to step through each number string in turn, returning the number string as Z$ when RETURN is executed on an asterisk being found (line 1020). The two data access routines (lines 110 to 140 and 150 to 180) after the initialisation of NSTRING could occur anwhere in the program. The data can be accessed in an order by suitable manipulation of the access instructions (e.g. the reverse loop in lines 150 and 180), and NSTRING can be re-initialised as zero at any point. Counting loops could be used to access an Nth item of data. Spectrum users should note that the Spectrum has READ and DATA functions (which are dealt with in Section W), that provide a more convenient way of storing and retrieving data for many applications, but are less flexible than string storage in some cases, especially when used as illustrated below. DATA items must be keyed in within the program listing and cannot be input. 5 REM *INITIALISE* 10 DIM A(10) 20 LET А5-"" 317 REM *DATA INTO STRING* FOR Е-1 TO 10 INPUT NUMBER LET А$=А$+5ТА$ NUMBER+"*" NEXT F REM ....... REM ....... REM ....... REM *RESTORE START* LET NSTRING=0 FOR Е-1 TO 5 GOSUB 1000 LET A(F)=VAL ZŠ NEXT F FOR F=10 ТО 6 STEP -1 GOSUB 1000 LET A(F)=VAL Z$ NEXT F РРР MEN жола» ЅТОР REM ***READ STRING SUB*** LET Z$-"" LET NSTRING=NSTRING+1 IF AS(NSTRING)="*" THEN RET URN LET Z$2Z$4A$ (NS TRING) GOTO 1010 318 SECTION U: THE COMPUTER MEMORY U1: Memory Organisation Digital computers operate with sequences of numbers in the binary number system. Binary numbers are numbers to base 2, and our ‘normal’ number system is decimal (base 10). The BINARY system uses only two digits, 0 and 1. These are binary digits (bits). The computer holds a bit as a voltage level ( + 5v or Ov) іп a switched pathway. In the decimal system, a number, for example 418, is coded as a number using the digits @ to 9. The coding is based on powers of ten. 418 means: (4 times 10 to the power 2) +(1 times ten to the power 1) + (8 times ten to the power 0). (4x 10” + (1x10) + (8х 10’) 400 + 10 + 8 = 418 The binary system of coding uses powers of two in exactly the same way. The number 13 is represented as: (1x 2") + (1x27). € (0x2) + (1x2? 1 1 0 1 Binary number 1101 8 + 4 + 0 + 1-13 Decimal equivalent The binary number 101110 is evaluated as: (1 x 27) + (0 x 2) + (1x 2°) + (1 x 2”) + (1 x 2)) + (0 x 2^) 32 + 0 2,2%. Ü + 8 + 4 + = 46 in decimal Key in the following program, which converts decimal numbers to their binary representation: 1 REM *DECBI* 2 REM CONVERTS DECIMAL TO BINARY NUMBERS 10 PRINT “ENTER DECIMAL NUMBER 20 INPUT N 30 PRINT М; 40 LET BS="" 50 LET L=INT (N/2) 60 LET BzN-2*L 70 IF B=1 THEN LET А5-"1" 80 IF B=@0 THEN LET AS="9" 90 LET BS=AS+BS 100 LET N=L 110 IF L>@ THEN GOTO 50 120 PRINT " IS ";В5;" IN BINARY" Input sequences of numbers to familiarise yourself with the binary system. The program only deals with positive whole numbers. Trace 319 the progam to see how it works, using the examples 13 and 46 given above as inputs. Non-integer numbers are dealt with by using an exponent, as with the E notation system for decimals. Binary numbers have a binary point, and bits to the left of the point are binary fractions, representing the reciprocal power of two. The binary number 1.101, for instance, represents: GN FEM pe (1x2) + (91) +( 9) + (93) 1 + 5 + 0 + .125 -1.625 You may have noticed that binary numbers as seen above are all positive. Negative numbers are dealt with by using a particular form of binary representation. The method by which the ZX81 and Spectrum store numbers is described later in this Section. In a computer, numbers are held in fixed numbers of bits. These are referred to as words. A BYTE is a sequence of 8 bits. The sequence of 8 bits represents a number between 0 and 255 decimal, 00000000 and 11111111 binary. The ZX81 and Spectrum use 8 bit words, i.e. 1 byte. Memory in computers is organised as a linear sequence of addresses. Each address is a memory location or memory cell holding a single byte. The binary numbers in these locations are interpreted as numbers, characters or instructions depending on their context in the computer memory. The organisation of the memory is constant, but the space occupied by each area of memory varies according to the program and its requirements. As an obvious example, a long program takes up more space for storage than a short one. Memory is of two types: READ ONLY MEMORY (ROM) is fixed and cannot be altered. It contains the BASIC interpreter program, and is built-in to the computer in manufacture. RANDOM ACCESS MEMORY (RAM) is variable, multi- purpose memory that holds the current program and all the other elements of data required to run the program. Data can only be extracted from ROM (‘read’), and is permanent. RAM memory can be both read from and written to. Inserting a value into a memory location in RAM (writing or storing) will wipe out or overwrite the existing data at that address. Memory capacity is referred to as the number of Kilobytes (k) involved. Kilo refers to one thousand, but this is only approximately true, since a kilobyte is actually 1024 (2”) bytes. The ZX81 has 8k of ROM memory and, with the memory expansion, 16k of RAM. The 320 Spectrum has 16k of ROM and either 16 or 48k of RAM. The memory is organised as shown in the diagrams below (called memory maps). The ZX81 and Spectrum have somewhat different memory organisations. We will deal first with the ZX81, and then the Spectrum. Spectrum users should read through the ZX81 section, however, as definitions of the functions of various types of memory are covered in this Unit. ZX81 MEMORY МАР Address Contents 32767 GOSUB STACK Unused addresses. No memory 16509 16384 space exists for this area. 8192 ROM memory area. BASIC interpreter and operating system program. 0000 Тһе top of memory (КАМТОР) is usually вес ав shown оп switch-on, at 32767. The computer can be instructed to set RAMTOP at some lower value, to leave spare memory locations which can be used to store machine code programs, which are called (like subroutines) from the BASIC program with the USR instruction. Machine-code programming is outside the scope of this text. Some areas of memory are organised in the form of a stack. This is a system such that the last item entered will be the first to be pulled off 321 the stack. A number may only be placed on the top of the stack of existing numbers, and the only accessible number 15 the one on the top. This creates an ordered sequence. In the GOSUB stack this is used to ensure that the RETURN instructions are followed in correct sequence. Each GOSUB instruction causes the following line number to be added to the stack. RETURN then takes the first line number off the stack to get the correct line number to pass control of the program back. The machine-stack memory area is used to keep track of the operation of the program. The spare memory area is that portion of the allocated area not occupied by the program and other memory areas. Although we referred to the top of the stack, it is more correctly the free end of the stack on to which the numbers are placed. The free end of the machine stack is at the bottom, in terms of the memory address sequence, hence the spare memory is below the machine stack in our diagram. The calculator stack is used for arithmetic operations. The work space holds the program line being input and provides temporary storage for data being manipulated ~ a scratch pad. The variables area stores all variables initialised in the course of a program. They are held in various forms, and we shall deal with the way numbers and variables are stored in the next Unit. The display file has been covered in Section O. The program area contains the program lines. This area always starts at address 16509. All other memory areas ride on top of the program area, moving up or down as the program lengthens (has program lines added or inserted) or shortens (has lines deleted), apart from the GOSUB and machine stacks, which are always at the top of memory. The systems variables area holds the special variables which store information concerning the state of the computer for use by the operating system. Certain of the system variables were introduced in Section Q. Like the D-FILE system variable introduced there, some of these variables hold the addresses of the divisions between the areas of memory. Other variables hold values of addresses, line numbers, characters, etc., to keep track of what state of affairs is current in the operating system. You have seen, for instance, that the DF-SZ variable stores the number of lines on the lower part of the screen. Some other system variables are dealt with in the next Unit. There are a fixed number of system variables, and their values are always held at known addresses between 16384 and 16508. The names of the system variables are not recognised as BASIC variable names, but are just mnemonics for the system variable function. On the ZX81 there is no memory corresponding to addresses 8193-16383. Addresses 0 to 8192 contain the system software in ROM which holds the BASIC interpreter and operation program in machine code. 322 SPECTRUM MEMORY MAP Address Contents 32767 (16k) USER DEFINED GRAPHICS 65535 (48k) ROM AREA. BASIC INTERPRETER RAMTOP RAM 23734 23552 23296 22528 16381 AND OPERATING SYSTEM PROGRAM 0000 The memory тар of the Spectrum memory is somewhat different from that of the ZX81. The Spectrum also comes in two versions, one with 16k of RAM, one with 48k. The ROM is also larger on the Spectrum, occupying 16k. Thus the first 16k of memory addresses (0000 to 16383) are occupied by ROM on the Spectrum. A 16k version then has the next 16k of memory as RAM, up to address 32767. The 48k Spectrum uses addresses 32768 to 65535 for the additional RAM memory. Apart from the size of memory, the arrangement of memory is the same in both Spectrum versions, as shown on the diagram. The fixed memory points are given as the memory address. The Spectrum memory requires more separate areas (reserved for the additional functions of the Spectrum), and the organisation is somewhat different. Working from the top of memory down, we notice an area set aside for user-defined graphics. This occupies 168 bytes, 323 and is set at the actual top of the memory, which is referred to as Physical RAM TOP. The bottom of the user-defined graphics area is the RAMTOP that the computer recognises as the top of memory. This leaves the user-defined graphics area protected from any interference by the operating system. On switch-on, the address of RAMTOP is thus set at 65367 with a 48k Spectrum, 32599 on a 16k version. This is the memory address of the last existing byte of memory before the user-defined graphics area. Below this are the GOSUB stack and the machine stack, with the area of free memory below this, as on the ZX81. The calculator stack, work space for lines being keyed in or data being processed, and the variables storage area are all in the sequence followed by the ZX81 memory. Then we have a significant difference between the two memories. The display file on the Spectrum 15 fixed, and does not appear above the program area, but at the bottom of RAM. Between the program area and the display file are Spectrum- specific areas, concerned with input and output and colour. The channel information area has information required for the operation of the printer, the keyboard, and the ТУ screen in terms of its division into top and bottom screens, the bottom one expanding if necessary to contain the required lines. This area is adjacent to an area of memory that will be used to store data necessary for the operation of the Sinclair microdrive disc system when it becomes available and is attached to a Spectrum. This area ‘vanishes’ without the microdrive and there is no sequence of memory bytes allocated to it. This area begins at address 23734. Without the microdrive, this address becomes the start of the channel information area. System variables occupy 182 bytes of memory, from 23552 to 23733 inclusive. The printer buffer on the Spectrum is larger than that on the ZX81 because of the need to store information about each of the 8*8 points in a character cell (where the ZX81 only needed to store character codes). The buffer, to store a full line for the printer, needs 256 bytes. This is because each line of points іп а 32 character line needs 8*32 bits, and there are 8 of these lines needed to make up a line on the printer. This buffer occupies the bytes from 23296 to 23551 inclusive. The colour attributes (see Section W for this) occupy one byte per character cell, so the storage is 24*32 bytes from 22528 to 23295. These store the information about the colour (background and printing colour), brightness and flashing characteristics of each PRINT position. This information, together with the display file, determines the screen display. The display file holds the information about the pattern of dots to be placed on the screen, and the attributes file the additional data for a colour display. The display file occupies the memory addresses from the start of RAM (16384) to 22527. This is 6144 bytes, so we can note that on a 16k Spectrum some 42% of RAM is needed for the display and attributes files only. This leaves about 9k 324 for program and operating areas, and illustrates the fact that high- resolution graphics take up large amounts of memory. Below 16384, the memory addresses are all ROM memory. The more complex operating system of the Spectrum demands more Instructions in ROM than are required by the ZX81. There is no gap in memory at all on the 48k machine, all 64k of memory that the Z80 A chip (the central processing unit) can address being used. On the 16k Spectrum, of course, the memory addresses above 32767 are unused. U2: PEEK and POKE The PEEK and POKE instructions have been introduced for specific purposes in connection with the display file and character storage. This should have given you some understanding of their uses. Now that you have been introduced more generally to the way memory is stored in a computer, you will notice that these instructions provide direct access to the memory of the computer. PEEK N returns the value (in decimal notation) of the number stored in binary form in the memory byte of address N. In the ZX81, N must be in the range @ to 8192 to return the contents of ROM memory, and in the range 16384 to 32767 to return the contents of RAM. For the Spectrum, ROM extends from @ to 16383, RAM from 16384 to 32767 (16k version) or 65535 (48k version). POKE M,N places into the memory address M the binary form of the decimal number N. N must be in the range @ to 255 (to fit in a single byte). For the ZX81, and 16k Spectrum M must be in the range 16384 to 32767. The 48k Spectrum uses addresses up to 65535. ROM may not have values POKEd into it. In general, we use PEEK to extract from memory any values useful to our program, and POKE to insert values into memory. Remember that the values (entered and returned in decimal notation) can be numbers, characters or instructions. Machine-code programming is performed by POKEing into a specified sequence of addresses the values which correspond to instructions which the 780 central processor chip understands. This sequence of instructions is then called from within a BASIC program, in a similar fashion to calling a subroutine, and is executed. At the end of the machine-code program, a return instruction passes back control to the BASIC program. We will use PEEK to investigate how numbers and program lines are stored in the ZX81 and Spectrum. Different types of number have different formats in which they are held. The normal number in 325 memory is held іп 5-5yte floating роті binary form. Each number is stored in 5 bytes of memory. The (те numbers in a program are stored in 2 bytes of memory. Numbers in a program listing are stored as their printed characters, then in 5-byte form. Enter the program below if you are using a ZX81. It PEEKs the memory locations from address 16509 onwards, 1.e. each address in memory from the start of the program listing, after printing out the numbers as instructed in the first three lines, and prints the address, contents of the address as a decimal number, and the character string corresponding. The corresponding program and output for the Spectrum is given after the ZX81 has been dealt with, since the character codes are different. 5 REM "PROGLIST" 10 PRINT 23 20 PRINT 123E8 30 PRINT 123E-8 40 LET A=16509 50 PRINT A;TAB 10;РЕЕК A;TAB 1 5;CHR$ (PEEK A) 60 LET A=A+1 70 GOTO 50 You will get a display (use COPY to get a printer listing, and CONT to continue) that looks like this: 23 19300000000 1.23E-65 165809 e 16510 ла = 16511 ла ж 16512 e 16513 245 PRINT 16514 зе 2 16515 93. 5 16516 126 7 16517 153 Е 15518 56 5 16519 а 15520 ә 15521 15522 1:5 * 16523 16524 го - 16525 13 E 16526 16527 245 PRINT 16528 29 1 16529 3@ 2 16530 зі З 16531 42 Е 16532 зе 8 16533 126 2? 16534 ie2 B 16535 55 R 16536 72 7 16537 198 LE? 16538 192 " 16539 118 7 16540 16541 зе 2 16542 14 16543 16544 245 PRINT 16545 29 1 16546 за 2 16547 gi 2 16548 42 E 18549 22 - 16558 зе в 16551 126 ? 16552 199 7 16553 27 9 15554 22 = 163553 122 = 16556 le? Ф 15557 118 Y 16558 e 16559 406 с 16562 15 = 16561 16562 241 LET 16563 A 16564 20 = 163565 29 1 165656 3d & 1655? 33 5 i6568 2o e 155692 з” 9 Notice first the way the ZX81 changes the format of the numbers. 23 prints as 23, but 123E8 is printed as 12300000000, and 123E-8 as 1.23E-6. The operating routines put each number into a standard format for printing to the screen. In order to present a listing of the program, which is what you’ve typed in, the computer must hold two forms of the number; first the literal characters and second the 5-byte floating point form. Inspect the printout from the program. The first address printed is 16509, holding zero. This is the first of the two bytes holding the line number. Notice that the more significant byte comes first. This is the other way round from normal 2-byte values (those of the system variables, for example). Since the line number is less than 255, the first byte holds zero and the second (16510) holds 10. 16511 holds 10 again. This is the number of characters in the line. 16512 has zero, since these two bytes hold the line number as (First byte value) + 256* (Second byte value), in the standard way. 16513 holds the value 245, representing the keyword character PRINT. Then come the characters 2 and 3 (codes 30 and 31). Bytes 16516 to 16521 hold the values 126, which indicates that the next sequence of bytes holds a number, and then 133,56,0,0,0. This is the 5-byte form of 23. We shall see in the next Unit the mechanics of this way of representing numbers. Check through the rest of the listing and make sure that you understand how and why the memory addresses contain the values they do. SPECTRUM PROGRAM LISTINGS The program below for the Spectrum has a different form from that for the ZX81. This is a consequence of the strange results of the control characters in the Spectrum character set if used as a CHR$ (see Unit P2). We must avoid using a PRINT CHR$ instruction for these control characters. The program sets a logical condition to test the value of A in lines 60 and 70 which prints “CONTROL CHR” instead of the CHR$ form if the printing of the CHR$ would cause problems. 10 PRINT 23 20 PRINT 123E8 30 PRINT 123E-8 327 40 LET A=(PEEK 23635+256*PEEK 23636) 50 PRINT A;TAB 10;PEEK A;TAB 1 5; 6@ IF РЕЕК A>23 OR PEEK A<15 T HEN PRINT CHR$ (PEEK A) 70 IF PEEK А<-23 AND PEEK A>=1 6 THEN PRINT “CONTROL CHR" 80 LET A=A+1 90 GO TO 50 The results will be as follows. (Use scroll to see the full listing. To get a printout like the one here, you must BREAK the program when “Scroll?” appears, then use COPY, then CONT to get the next screenful.) 1.2ЗЕ +19 1.23E-6 23755 e ? 23756 10 > 23757 10 ? 23758 ә ? 23759 245 PRINT 237862 Ea 2 23751 51 3 23762 14 > BATES © s 23764. e ? 257855 23 CONTROL CHR 23756 e > 23767 e т 23768 13 23752 e ? 23770 го CONTROL CHR 25771 13 patya © “y 23773 245 PRINT 2377 49 1 23775 sa 2 23776 51 3 597727 вә Е 23778 56 а 23779 14 ? 23780 162 5 23781 =s ? 23782 72 H 23783 198 AND 23784. 192 USR 23785 13 23786 ә т 237857 зә Е: 53788 14. % 23789 © ? 23720 245 PRINT 23791 49 1 23792 sa 2 53793 51 5 23794 БӘ Е 23795 45 m 23796 56 a 23797 14. ? 23798 189 ш 23799 3 = 235800 22 CONTROL CHR 23801 122 > 23802 за? К 238903 13 The PEEKs in line 40 set A to the value of the first memory address of the program storage area. (See the description of the System Variables in the next Unit.) Unlike the ZX81 the Spectrum program area moves around in memory. After printing the numbers, in a revised notation, setting the exponent values to have the decimal point after the first digit (a task 328 automatically done by the operating system) the program prints the first address (23755), which is the first byte of the program area. It then prints the value stored in this byte, followed by the character code (if it’s not a control character). Codes not corresponding to a character with a printed form produce a question mark. The first two bytes hold 0 and 10. This is the line number, stored, unlike all other two-byte numbers, with the more significant byte first. The next two bytes hold the number of characters in the line, stored in normal fashion, with the least significant byte first. We then have code 245, which is the keyword PRINT, the first instruction in the line. This is followed by the characters 2 and 3, for printing in the program listing. This is followed by code 14, which is a control code indicating that the next 5 bytes are to be interpreted as a number. There are then five bytes storing the number 23, in the special form in which the Spectrum handles integers. We will deal with this in the next Unit. Notice that the code 14 defines for the Spectrum the way in which a character or number (stored in the same binary form in a memory byte) is to be interpreted. After the five bytes of the number comes the ENTER character (13), signifying the end of the program line. Addresses 23772 and 23773 hold the next line number, then comes the number of character bytes in the line, and so on. Note that the number 123E8, which was input in this form, is stored as this sequence of characters, even though it prints in a different form, due to the operating system using the five-byte form to decide what number is to be printed. Trace the program further than the third line we have included in the printout, and ensure you can follow the program line arrangement, as we will refer to this in connection with a program to renumber program lines automatically later in the text. Although the Spectrum and ZX81 character codes are different, the program line arrangement is the same. Because we know that the address at which a program listing starts can be found, and the format of the program listing in memory, we can use PEEK to extract data from a program line. This can be useful to store data. Enter and run the program below. You should be able to see how it works. Remember that the first character after the line number (two bytes) and the line length (two bytes) will be the REM statement. The characters to be PEEKed will follow this. 5 bytes therefore need to be added to the start address of the program area. The Spectrum user needs to use the PEEK expression to find the start of the program (the address given by M): 40 REM RIALCNIS 20 LET M= PEEK 23635+256# PEEK 22636 30 PRINT АТ 10310 40 FOR F=7 TO 0 STEF -1 S50 PRINT СНЕ% PEEK СМ+5+Р); &O NEXT F 329 On the ZX81, the start of the program area is fixed. 5 can be added to this to give the address of the first byte of memory we are interested in (16509 + 5 = 16514). 10 REM RIALCNIS 20 PRINT AT 10,10; 30 FOR F=7 TO @ STEP -1 40 PRINT CHRS PEEK (16514+F); 50 NEXT F The reverse procedure is also possible, using POKE. Try this program. ZX81: 18 REM ABCDEFG 20 FOR F=0 TO 6 30 POKE (16514+F) , 29+F 40 NEXT F Spectrum: 10 REM ABCDEFG 20 LET М-РЕЕК 23635+256*PEEK 23636 30 POR F=0 TO 6 40 POKE (M+5+F) ,48+F 50 NEXT F Тһе Spectrum program again uses а РЕЕК to find the program area start address, and the different character codes require different values added to F to give the same result. Run the program, then LIST it and see what has happened to the REM statement. If you want an illustration of the care needed when POKEing into programs, try setting F = 0 TO 8 and run the program again. LIST it, and then try to edit your listing. The ZX81 may crash, and if your screen blanks out or produces other strange effects you will have to reset it by pulling out the power supply plug and re-inserting it. The Spectrum is more tolerant of this sort of treatment, and will just give an error message, but the program listing is corrupt, and NEW will have to be used. Storing information in a REM statement in this fashion, given that as you have seen it can be accessed with PEEK and updated with POKE, can provide a useful alternative to storing data in variables. The layout of the program listing in memory, starting at a known address, enables us to write a program which will renumber the program lines. Here’s the program for the ZX81: 1 REM "RENUM" 2 REM REPLACE LINE AND STEP 30 REM VALUES IF START LINE 45 REM OR STEP VALUE TO BE DIFFERENT 50 REM RUN IN FAST MODE FOR 121 REM LARGE PROGRAMS 1001 REM **YOU MUST REMEMBER** 1002 REM ***GOSUBS AND GOTOS*** 9000 REM ***RENUMBER*** 9010 LET RAM=16509 330 9020 LET LINE=10 9030 LET STEP=10 9040 POKE RAM, INT (LINE/256) 9050 POKE RAM+1, (LINE-256*PEEK R AM) 9060 LET RAM=RAM+1 9070 IF PEEK RAM<>118 THEN GOTO 9060 9080 LET RAM=RAM+1 9090 IF 256*PEEK RAM+PEEK (ВАМ+1 )=9000 THEN GOTO 9120 9100 LET LINE=LINE+STEP 9110 GOTO 9040 9120 LIST 9130 STOP Modifications for the Spectrum are required as follows: Line 9010 must be edited to read LET R AM = PEEK 23635 + 256* PEEK 23636. Line 9070 must be changed to 9070 IF PEEK RAM<>13 THEN GOTO 9060. Line 9010 sets a variable RAM equal to the start of the program area. LINE (the line number to start the new listing) and STEP (the increment of the line numbers) are both set at 10, but could take any desired values. 9040 and 9050 POKE into the first and second bytes, which hold the line number, the value 1@. Into the first byte goes the line number divided by 256, the INT function turning this to an integer value. If non-integer values are POKEd into an address, they are automatically rounded, but to the nearest whole number, which does not give us the desired result if the remainder is 0.5 or greater. Into the second byte goes the line number less the value in the first byte, obtained by PEEKing the byte and multiplying by 256. Lines 9060 and 9070 increment the address and check if the address contains the NEWLINE (ENTER) character (code 118 on the ZX81, code 13 on the Spectrum), repeating until a new line is found, which marks the end of a program line. 9080 adds 1 to RAM, giving the start address of the next program line. Line 9090 checks the value (line number) held in this and the next byte, to see if the process has reached the start of the renumber program, passing control to 9120 for listing if it has. 9100 increments the line number by the step value and control is then passed back to line 9040, and the new line number POKEd into the first bytes of the next program line. Notice that the program checks each byte in turn. Another way to find the address of the end of the program line, which prevents the need for this, is to use the data about line length stored in the third and fourth bytes of the program line. To do this, delete line 9080 and replace lines 9060 and 9070 as follows: 9060 LET LENGTH = PEEK(RAM + 2) + 256*PEEK(RAM + 3) 9070 LET RAM = RAM + LENGTH + 4 This finds the line length, and adds this, plus 4 for the bytes holding 391 line number and line length, to the current RAM value, giving the address of the first byte of the next line. Remember, to use a program like this on the ZX81, you should LOAD it before you start to program, and use RUN 9000 when you have developed your program. You will also need a STOP instruction before line 9000 to prevent your program renumbering itself every time you run it. The REM statements are not necessary to the program in the listing, of course, but do give the program something to renumber as a test. Note that GOSUB and GOTO destination line numbers are not renumbered, and you must edit the lines affected to suit the new numbering. Take a printer listing or note down the relevant lines before renumbering! On the Spectrum, a program can be MERGEd with one already in memory, and added at any time. See Unit W2 for this facility. Loading useful programs, Joined into a subroutine or sub-program toolkit, is worthwhile if you are developing a large program. This might include, for instance, a sorting routine, error message and format subroutines. As with the renumber program, which is deleted after use, any unwanted routines can be edited out. A utility program like this should obviously have line numbers 9000 + , and the variables used should not be single letter variables, or even variables such as A9, which might be needed in the main program. The program “TOOLS” in the program library illustrates the principle, and provides a basis for you to add further useful subroutines. It incorporates a block deletion routine (also listed separately), which enables easy deletion of any portions of the toolkit program not required to be easily edited out. This includes the facility to delete itself! U3: System Variables The system variables area of memory 1s a fixed area holding 125 bytes (ZX81) or 181 bytes (Spectrum) of system variables. These occupy either one or two bytes, generally, but exceptions include the variable PRBUFF on the ZX81 (16444 to 16476), which stores 33 characters in a line, ready for the printer (the printer buffer), the MEMBOT variable on both machines, which is a subsidiary number store used in conjunction with the calculator stack, and KSTATE and STRMS on the Spectrum, dealing with the keyboard and Input/Output respectively. Single byte variables store a number between @ and 255 decimal. A two-byte variable holds a number between 0 and 65535. This is because the number of bytes available is 2, hence there are 16 bits, which can store 65536 values (@ is a value). To calculate a two-byte value in decimal, which we must do because this is how values from addresses are returned by the computer, we use (value of least 332 significant byte) + 256* (value of most significant byte). Except in the case of line numbers for program lines, the first byte is the least significant byte of any two-byte number. The set of system variables we will look at are those variables which hold the addresses of the boundaries between areas of memory. Since some memory areas move around, the computer must know where each area starts. We can also use this information to find out what the current state of memory organisation is for use in various ways. Below are tables of the ZX81 and Spectrum memory maps with the system variables and their addresses. Note that the system variable names are Just mnemonics. They are not recognised by the computer. ZX81: MEMORY MAP WITH SYSTEM VARIABLES Memory Area System Variable Addresses Contents Returned by: System Variables (Fixed) (16384) (Fixed) (16599) Program Listing D-FILE 16396/7 PEEK 16396+256*PEEK 16397 Display File VARS 16400/1 PEEK 1649@+256*PEEK 16491 Marker Byte (Single byte containing CHR$ 128) E-LINE 16404/5 PEEK 164044256*PEEK 16495 Work Space STKBOT 16410/1 PEEK 16419+256*PEEK 16411 Calculator Stack STKEND 16412/3 PEEK 16412+256*PEEK 16413 Spare Memory Machine Stack Gosub Stack The size of various portions of memory occupied on the ZX81 can be found by entering (as direct commands) the following: (Stack pointer-not accessible with BASIC commands) ERR-SP 16386/7 PEEK 16386+256*PEEK 16387 RAMTOP 16388/9 PEEK 16388+256*PEEK 16389 Program listing: PRINT PEEK 16396 + 256*PEEK 16397-16509 Program, variables, display file and system variables: PRINT PEEK 16404 + 256* PEEK 16405-16384 Approximate memory left for program: PRINT PEEK 16386 + 256*PEEK 16387 - PEEK 16412 — 256*PEEK 16413 333 This returns only the approximate number of free memory bytes, since it does not take into account the size of the machine stack, because we cannot access the stack pointer. Actual memory is always less than the value returned. SPECTRUM: MEMORY MAP WITH SYSTEM VARIABLES Memory Area System Variable Addresses Contents returned by: P-RAMT 2373273 PEEK 23732 +256*PEEK 23733 User Defined Graphics UDG 23675/6 PEEK 23675 +256*PEEK 23676 RAMTOP 23730/1 PEEK 23730 +256*PEEK 23731 STORAGE Note that various marker bytes are used to separate areas of memory, as indicated. Program length (listing only) is given by (PEEK 23627 + 256*PEEK 23628) - (PEEK 23635 + 256*PEEK 23636), i.e. VARS less PROG. Program and variables memory requirement is given by E-LINE less PROG, with the PEEKs required again as given above. All memory areas below 23734 are fixed, with their addresses being as given in the previous Unit (see the Memory Map diagram). Without the microdrive, CHANS will be fixed at address 23734. An alternative method of determining free memory left on the Spectrum is to use the following, which uses a routine in the ROM memory. The Not accessible with BASIC Not accessible with BASIC STKEND 26353/4 PEEK 26353 +256*PEEK 26354 STKBOT 26351/2 PEEK 26351 +256*PEEK 26352 WORKSP 23649/59 PEEK 23649 +256*PEEK 23659 E-LINE 23641/2 PEEK 23641 +256*PEEK 23642 VARS 23627/8 PEEK 23627 +256*PEEK 23628 PROG 23635/6 PEEK 23635 +256*PEEK 23636 CHANS 23631/2 PEEK 23631 +256*PEEK 23632 Fixed (23734) 334 number of bytes of free memory 1.е. the size of the spare memory section, is given by PRINT 65536 - USR 7962. We can use the system variable VARS to determine how numbers are stored in the computer. Each different type of variable needs to be identifiable as the correct type, 1.е. as a loop control variable, as a string variable, etc. This is done by altering the first three bits in the appropriate letter codes. (Bits in a byte are actually numbered right to left, starting from 0. In the eight bit byte 00100000 , for instance, bit 5 is set as 1. Bits 5, 6 and 7 in the byte are the ones referred to above.) On the Spectrum, all letters in variable names are taken as lower case. These letters all have bit patterns starting 011. . . , codes being 97 to 122. The ZX81 letter codes all start with bits 001 . . . , codes 38 to 63. Check the binary equivalents of the letter codes to confirm this. Since these three bits are always the same, the computer can alter them as a signal to indicate which type of variable is being called by a particular variable name, which may be the same as the name of some other type of variable (e.g. A as a simple variable, A(5) as an array variable, A$ as a string variable). The patterns of bytes used are as follows: Single character variable did... Multiple character variable 101... Loop control variable Lion String variable BID. ..... Numeric array variable 100..... String array variable (BI PS Because the codes for the letters have different values on the ZX81 and Spectrum, the effect on the value stored in the byte is different. After we've discussed exploring the ways variables are stored, the form for each type of variable is given, with the change in the letter code noted for both the ZX81 and Spectrum. The next program inputs a value for the numeric variable A. This will be entered into the VARS area as the first variable stored. Line 30 PEEKs the value of the VARS system variable, and adds the value of the loop variable F, then PEEKs this address. The first value returned by the expression in brackets (F = 0) is the address of the first byte of the variables store. For a numeric variable on the ZX81, this holds the name of the variable, stored as its Code + 64, if the variable name is a single character. On the Spectrum it 1s stored as the code of the /ower case letter, unchanged. Key in the program and input various numbers. 10 INPUT A 20 PRINT "A-";A 30 FOR F= 0 TO 5 49 PRINT PEEK (PEEK 16400--256%Р EEK 16401 +F) 50 NEXT F 68 GOTO 10 235 Spectrum users: change the PEEK expression to: 40 PRINT PEEK (PEEK 23627 + 256*PEEK 23628 + F) Input 1.5. The display will be like this: ZX81 Spectrum А-1.5 А-1.5 102 (= Code А + 64) 122 ( = Code of lower case a) 129 (5 byte number follows) 129 (5 byte number follows) 64 64 0 0 0 0 0 0 Change the variable name in line 10 to confirm the code. The first byte of the 5-byte number is the exponent byte, the following four are the mantissa, the number the exponent acts on to get the numeric value. The Spectrum has a special form of this for integers. (See below for more on numbers.) Change the variable name to, for example, AB5, or other variable names with more than a single letter in the name, and run the program again. You can then confirm that numeric variables are stored in these forms: Single Character Variable 1 byte 5 byte number Code Exponent Four Mantissa bytes +64 7Х81 byte (S = Spectrum) +9 s Multiple Character Name Variable 1 byte 1 byte (for each character) 1 byte byte numbe Code Code Exponent Four Mantissa bytes +128 2Х81 +64 5 First character and last character only are stored as code plus values indicated. Other characters are stored as the standard character codes. The other forms of variable are stored in the byte sequences shown below. Write programs to confirm these memory arrangements. You will need a loop that prints the correct number of bytes. The FOR- NEXT sequence, for example, which takes 18 bytes, can be simply programmed by deleting lines 10, 20 and 60 in the program above, and changing the loop to @ TO 17. 336 Loop Control Variable 5 b e numbe ° 2 Code Start value Limit value Step value Line number +192 Zx81 for next jump +128 S The control character is stored as code + 192 on the ZX81, + 128 оп the Spectrum. The value is incremented or decremented by the step value each time the NEXT instruction is executed, and the value checked against the limit value after each such change. The line number (stored as more significant byte first, as are the program line numbers) is the line number of the FOR...TO instruction plus 1, as this is the destination line for the NEXT instruction to jump to. String Variable The single letter name is stored as the code less 32 on both the ZX81 and Spectrum. The number of characters is what is read by the LEN instruction. For a null string, this is zero, and no character bytes are stored. Numeric Array Variable 1 byte 2 bytes 1 byte 2 bytes 2 bytes 5 bytes each eleme Code Number of bytes umber of Size of Size last +96 2Х81 following dimensions first dim. dim. +32 S Notice that an array such as A(7) is a single dimensioned array. (It will require 1+2+1+2+(7*5)=41 bytes.) The bytes storing the size of each dimension enable the computer to keep track of a multi- dimensioned array stored in a linear sequence. For example, DIM A(3,3) sets a sequence of the eight data bytes, plus 9*5 bytes to hold: t — Te —P 1.3 ae 2,1 — 2,2 — À 2.9 Cop 21e 22 eni Work out how a 3-D array, say A(2,3,4) will be stored. 337 String Array Variable 1 byte 1 byte 2 bytes No. of |Size of first dims. dim 2 bytes Ho. of bytes following 2 bvtes 1 byte per chy. Length of Code strings You should now see why string arrays must have fixed length strings, since otherwise the computer could not use the length of string datum to step through the linear sequence to find the appropriate set of character codes making up an element in the array. The next manipulation we will look at concerns the way the ROM memory holds the characters to be printed on the screen. Starting at address 7680 on the ZX81, and at 15616 on the Spectrum, each character is held in a sequence of 8 bytes of memory. The binary number of each byte represents, in this case, a sequence of 075 and 175, which hold the pattern of the character, corresponding to the 8 x 8 grid of points in each character cell on the screen which is used to print a character. If we take the letter A, for example, it 1s represented like this: DECIMAL BINARY NUMBER NUMBER 0 00000009 60 00111100 66 01000010 66 01000010 126 01111110 66 01000010 66 01000010 0 00000000 А zero is read as an instruction to leave blank the corresponding point on the screen, and a 1 indicates it is to be blacked in. The following program will illustrate the principles. It takes one of the 8-byte sequences of numbers stored in ROM and gives the decimal and binary forms of these numbers. The pattern of ones can be seen. Remember Decimal 0-255, Binary 00000000 to 11111111, is held in each byte. The relevant portion of memory is accessed by using the code of the character concerned. Starting at address 7680 on the ZX81, the first of the addresses for any character is given by 7680 + CODE (Character)*8. The eight addresses are then PEEKed one by one, and the decimal number given then the binary form printed out. Lines 110 and 130 convert the decimal to binary and print it. Whilst the Spectrum characters are held at a specific address in ROM, the system variable CHARS, which is at addresses 23606 and 23607, holds the start address of the character memory sequence, and 338 can be POKEd with different values to start the sequence elsewhere in memory. This can be used to define a new start point for the character set in RAM, and define a whole new character set on the Spectrum, in addition to the facility for user-defined graphics (which will be dealt with in Unit W2). CHARS returns a value which is the start address of the characters, less 256. The character set that is stored in ROM starts with the Space symbol (code 32) and runs in sequence to © (code 127). To access the right sequence in ROM, we must use the start value given by CHARS, which is 15360, plus the character code multiplied by 8, just as on the ZX81. The fact that CHARS points to 256 bytes below the start of the printable character set adjusts for the fact that the first character that can be accessed has code 32 (since 32*8 = 256). For the program below, therefore, Spectrum users need to put LET A = 15630 in line 10, which is the normal value given by PEEKing the CHARS system variable, and the right address in ROM is accessed. 10 LET A=7680 20 PRINT “INPUT A CHARACTER" 30 INPUT А5 40 CLS 50 LET C=CODE А5 60 LET D=8*C+A 70 FOR X=0 ТО 7 80 LET L=PEEK (D+X) 90 PRINT D+X;TAB 6;L 100 FOR Z=18 TO 11 STEP -1 110 PRINT АТ X, Z;L-2*INT (L/2) 130 LET L=INT (L/2) 140 NEXT Z 150 NEXT X If we add: 120 IFL-2*INT (L/2)- 1 THEN PRINT AT X,Z +10; “Ш” we can print out a large version of the character. The routine will only work for the standard characters and graphics (codes 1 — 63 on the 7Х81). Inverse characters and functions on the ZX81 are not held in this form. All Spectrum characters up to code 127 can be accessed. We can use this principle to produce any size character we want, within the limits of the screen. The next program allows a string of up to 4 characters to be printed out. You should be able to follow the same steps in this program as in the previous one - the method is essentially the same, working on a string of characters, rather than a single character, and only using the print routine. To fit 3 lines of 4 characters (which would take 24 lines) we neglect the first (top) byte, since this is blank for all the letters and numbers. This lets us fit 3 lines in, but graphics characters will look strange, since they do use the top line. A different method is used to read out the binary values for printing. To avoid complex manipulations of PRINT AT values, which would be required if we 339 used the system in the previous program, each line of the ROM is checked for each character in turn across the line, which enables a continuous PRINT operation. Each binary value is checked in turn to see if it is Ø or a 1 by doubling the value of X (line 180), so that it is either >128 (1) or <127 (0). Line 150 takes 128 away if a 1 is found. If you do not understand this process, take any binary number and trace the operation through lines 120 to 190. © REM "BIGFREINT" & REM xALLüWS = LINES OF 4 #CHARACTERS EY OMIT- *TING TOF LINE CELANE *FOR LETTERS AND xNLUMEERZ» OF xz GRID 10 DIM Ac43 20 PRINT "INPUT STRING (МАХ 12 LETTERS / МОМЕЕЕ >" 25 INFUT АФ 30 ELS 35 FEM *FOR EACH LINE* 40 FoR Fzi TO 3 = REM xGET CODE INTO ARRAY * xFOR EACH LETTER % SO FOR ісі TO 4 во LET ACLI= CODE АСЕ? 70 NEXT L 75 REM xUFDATE At So LET А%=А%(5 TO 3 ез REM «BYTES 1 TO 7 OF * * ж ж ж ж #ITHARACTER IN ROM + ЭО FOR B=1 TO 7 95 REM *FOR EACH LETTER OF % *LINE * 100 FOR C=1 ТО 4 105 REM *GET BYTE VALLE 110 LET X= PEEK (7@80+A(C) #8+B) 115 REM #FOR EACH BIT* 1209 FOR V-O Tü 7 125 КЕМ *IF ZERO THEN JUMP 190 IF Х«128 THEN GOTO 170 140 PRINT "Ш"; 145 REM #DECREMENT CHECK * жУЙІМЕ + 150 LET Х-Х-128 160 GOTO 180 170 PRINT " "i 120 LET Х-Хжу ісе REM xNEXT BIT* 190 NEXT V 19% FEM %МЕХТ LETTER OF LINE* 200 NEXT C 205 REM xNEXT BYTE OF RüOM* 210 NEXT Ë 215 REM *NEXT GERDOLF OF 4+ 220 NEXT F 220 REM #*ЕМП++ 340 Spectrum users must insert 15360 in place of 7680 in line 120. The program, ‘‘HEADLINER”’ in the program library, uses the character array in ROM to print banner headlines on the printer. If you inspect this program, you will see that it has a method of enabling the inverse characters of the ZX81 to be printed by changing them into normal characters (using CHR$(CODE А%-128)) to access the pattern in memory, then reversing it again when it comes to print it. RAMTOP may be set to a lower value to give memory space outside that usually used by the operating system. This has an application which is occasionally useful on the ZX81, regarding the use of CLS after SCROLL has been utilised. This does not apply on the Spectrum. Clearing the screen can take a long time after scrolling. Try this to illustrate: 10 FOR F=1 TO 30 20 SCROLL 30 PRINT "XXXXXXXXXXXXXX' 40 NEXTF 50 CLS This is due to the fact that SCROLL interferes with the way the display file is set up on a ZX81, with more than 3.25k of RAM available — with a full screen of spaces where no characters exist. A PRINT line after SCROLL is just the required length, with nothing filling up the line if there are no characters. To clear the screen, the ZX81 counts up 24 new lines, then inserts spaces to recreate a full display file. If less than 3.25k are available, an empty screen is just 24 newline characters. RAMTOP is set with 0 in address 16388 and 128 in 16389 оп switch- on (0 + 256* 128 = 32768, the address of the first non-existent byte). POK Eing values to set RAMTOP below 19634 (16509 + 3.25k) will set up the minimal display file and CLS will act instantly. Your program must be less than 3.25k (say 3k as returned by the commands given above). The convenient value to use is 76 poked into 16389. This sets RAMTOP as 0 (value of 16388 unchanged) + 256*76 = 19456, which is rather more convenient than POKE 16388,76 followed by POKE 16389,177 (177 + 256*76 = 19633). Insert 45 POKE 16389,76 into the program above and run it again. Note that if you NEW the program and then key in PRINT PEEK 16389, you will still get 76. RAMTOP must be re-set by POKEing the correct value (128) or by switching off and on again to re-set. On the Spectrum, RAMTOP is moved using CLEAR. The instruction CLEAR (N) resets RAMTOP to the address given by N. RAMTOP is reset to this value, and remains at this address until reset by CLEAR (or switching off and on again.) It is not reset by NEW. The procedure given below for storing data above RAMTOP is less useful than it is on the ZX81, because the Spectrum can MERGE a program with another LOADed in from tape (see Unit W2). This 341 program can be mostly data (although it must have program lines). However, this method will work on the Spectrum, and shows the technique of moving Information around in memory. If you progress to machine-code programming, this is one way in which you can store machine code. RAMTOP may be moved so as to reserve space at the top of memory. On the ZX81, this area will not be affected by NEW or CLEAR, or the automatic NEW that occurs with LOAD. It can be used to store data for use by another program, after the data have been defined by a previous program. This procedure, available with less complications on some computers, is performed as follows on the ZXO1. i) New values are POKEd into the RAM TOP system variable, so that the system considers the top of RAM to be lower than address 32767. This reserves space above the new RAMTOP value. NEW is then used. POKEing RAMTOP has no effect until NEW has been used. How much space is reserved depends on the number of bytes of data we require to store. (Spectrum: See above for resetting RAM TOP.) п) The program to use the data must have been written and stored on cassette. This has instructions to copy into the variables area the data stored. It must initzalise the same variables or arrays for data in the same sequence as the program which provides the data. ii) The program to store the data intialises the arrays or variables for the data first, before any other variables. The program is then run. The required number of bytes are taken from the start of the variables area (found using VARS), and copied to the area above RAMTOP (found using RAMTOP). iv) Program 2 is then loaded. It initialises the variables as did program 1, finds VARS and RAMTOP, and reverses the procedure, PEEKing RAMTOP and POKEing the values found into the variables area. It can then proceed to use the data. The amount of memory needed for storage is calculated from the information given above about the method of storage of variables. As an example, let us assume we want to store an array D(20) for use by another program. We will use this as a short example program. In practice, the technique will require a second program to use the data to have been written and SAVEd, but the examples are short enough to key in. Reference to the information about variables shows us that an array D(20) requires 106 bytes. On a ZX81, we must set RAMTOP as 32768 — 106 = 32662. This is the address of the first non-existent byte, and will be the address of our first storage byte. To set RAM TOP to this value, we POKE 16389,INT(32662/256) as a command, followed 342 by POKE 16388,32662 – 256*INT(32662/256). Of course you could use the computer to work these out beforehand, and POKE the values directly. NEW the computer, then enter this program and run it. On the Spectrum, RAMTOP is set with CLEAR, and can be done simply by using: CLEAR (PEEK 23730 + 256* 23731 – 106) 5 REM "DSTORE" 10 REM **DATA ABOVE RAMTOP** 20 DIM D(249) 30 FOR F-1 TO 26 40 LET D(F) =F*F 50 NEXT F 60 LET VARS=PEEK 164004256*PEE K 16461 70 LET RAMTOP-PEEK 16388+256*P EEK 16389 80 FOR Е=0 TO 105 90 POKE (RAMTOP+F) ,РЕЕК (VARS+F) 100 NEXT F The first active line (20) dimensions the storage array. The loop of lines 30 to 50 merely insert some values into the array. Lines 60 and 70 find the values of VARS and RAMTOP. The loop of lines 80 to 100 stores each byte of the variables store that contains array D above RAMTOP. Spectrum users must insert the correct PEEKs in lines 60 and 70 to get the values of the VARS and RAMTOP system variables. The same must be done with the data retrieval program below. Now use NEW, and enter the program to retrieve the data. This reverses the procedure. After initialising D(20), and finding VARS and RAMTOP, it POKEs the value of each byte stored above RAMTOP into the bytes of the variables area containing the array. Lines 70 to 80 print out the array values. 1 REM "DFEICH" 5 REM **RETRIEVE STORED DATA **FROM MEMORY ****** 10 DIM D(29) 20 LET VARS-PEEK 16400+256*PEE K 16401 30 LET RAMTOP-PEEK 16388+256*P EEK 16389 40 FOR Е-й TO 105 50 POKE (VARS+F) ,PEEK (RAMTOP+F) 60 NEXT F 70 FOR F=1 TO 20 80 PRINT D(F) 90 NEXT F On the ZX81 only, you can use CLEAR: the array will be wiped from memory, but remains safe above RAMTOP. Running the program again will retrieve the data once more. This is obviously a technique useful not only for passing data between programs, but also for allowing CLEAR to be used and still having current data (i.e. that not 343 assigned by LET statements) preserved. This does not apply to the Spectrum, since CLEAR re-sets RAM TOP. The complete list of system variables for both the ZX81 and the Spectrum is given in Appendix V. The timing variable FRAMES is used in the “КЕАСТ”” program analysed in Unit V3. MORE ON NUMBERS AND COMPUTERS The way in which numbers are manipulated by the operating system in a computer does not concern us here, but the way numbers are held, and their form, are important in computing, even if the precise manner in which calculations are carried out is a separate topic. We will deal here with enough detail of the binary system to enable 5-byte floating point to be understood. We briefly introduced the binary system earlier. To explain further the use of a system using powers of 2, and how any number can be represented % a certain level of accuracy, key in this program: 10 REM "POWERS OF TWO" 28 PRINT "POWERS OF Two" 30 PRINT "------------- " 40 PRINT "2**N";TAB 10; "М№";ТАВ 16;"2** -N" 50 PRINT 60 PRINT TAB 6;"1 0 1.9" 70 FOR F-1 TO 16 80 PRINT TAB ( 17-LEN STRS (2**F ));2**F;TAB 10;F;TAB (14+(F >3));2%%-Е 90 МЕХТ Е (Replace ** Бу # for the Spectrum at each occurrence in the program). You will get a display like this: POWERS OF TUO mx xM ч eee -M 1 & 23. c і e. 41. е е.гБ б a G. 1 15 4 . 0825 32 5 a 93125 64 ы «"ӘӨзбесе 128 а „ гат >= 256 а |. yl == S123 э -дәлзезіге 1924 18 -@B@2907SES5625 2048 із „ 5345525583065 4995 12 PAAS L 14065535 6192 13 |. їз YT = 71 163524 із „ асас 22351355 32768 15 „ зз ЗЫ Г БН 65536 isc «"Әсоелкгезуаә Notice that we have positive powers of two оп the right, giving integer values, and negative powers, giving fractions which are represented as ‘decimal decimals’. The emphasis in the comment above about accuracy stems from the fact that there are limits to the accuracy obtainable with every number system. The fraction 1/3 is never 344 accurately represented in the decimal system, however many decimal places are used. The same goes for many numbers in both decimal and binary notation. If you study the display it should be apparent that with the binary system, only numbers equal to certain decimal values are accurately represented. Decimal .6875, equal to 1/2 + 1/8 + 1/16 is accurately represented by binary .1011, for example, but with a single byte (8 bits), any number varying by .001953125 (2-7) above or below the value represented in the byte will appear the same to a computer reading this byte. To increase the accuracy of representation of numbers, a larger number of bytes is needed. This also allows larger numbers to be dealt with. The ZX81 and Spectrum use ‘‘5-byte floating point’’ representation of numbers. The ‘FLOAT’ program gives the decimal value held in each byte of the five by PEEKing the variables area: 1 REM *FLOAT* 2 REM FRINTS FLOATING FOINT FORM OF A NUMBER 10 PRINT "ENTER A NUMBER" 20 INPUT N ЗО PRINT "THE NUMBER "FN" IS HELD» "IN THE 7Х681 А5:-" 40 FOR F=1 TO Š 45 REM FEEKS START OF VARIABLE STORE (VARS) AREA IN MEMORY SO PRINT FEEK С PEEK 16400+2546 ж PEEK 16401-4F);" "3 60 NEXT F On the Spectrum you should change Line 50 to read PRINT PEEK (PEEK 23684 + 256*PEEK 23685 + F). Input only non-znteger values (we'll explain why this is the case a little later). If you input 2.4, you will get a screen display of: 130 29 153 153 154 Try other numbers. There is no obvious pattern to the decimal values, other than the first number not varying much from around 128 unless you input very large or small numbers. This is the exponent byte (as with the E notation). The next program, “ЕТУЕВҮТЕ”, displays the mantissa number (the other four bytes) in decimal and binary form, and the exponent byte in decimal form: 10 REM "FIVEBYTE" ZO PRINT “INPUT NUMBER" ЗО INPUT N 40 PRINT “NUMBER="7N 50 LET EXP= PEEK (1+ PEEK 1640 O+256% PEEK 16401) 60 PRINT “EXPONENT="; EXP 70 LET Р=ЕХР- 128 80. IF P <> -128 THEN PRINT “2 жж Hers Mats ++ Р 90 IF EXP=0 THEN PRINT “USED F OR ZERO ONLY" 345 100 PRINT "MANTISSA BYTES: -" 110 FOR F=2 TO S 120 PRINT TAB (F-2)#5; PEEK (F+ PEEK 182400-256% РЕЕК 16401); 130 NEXT F 140 ЕСЕ Е=2 TO S 150 LET D= PEEK ¿(F+ PEEK 16400+ 256% PEEK 16401) 160 LET Es$z"" 170 LET L= INT (0/2) 120 REM LET АФ=("1" AND П-72 + C"O" AND П-2ж-0) 181 LET A$- ZTR$ (D-Z*L>) 190 LET BS=A$+E% 200 LET IL 210 IF 050 THEN GOTO 170 220 IF LEN E$Z8 THEN LET E$z"oo o00000"c1 TO (8- LEN E$))+EËE%$ 230 FRINT TAE (F-20*8; E$ 240 NEXT F (Once again, on the Spectrum change ** to Î at every appearance. Line 50 needs to be changed to read LET EXP = PEEK (1+ PEEK 23684 + 256* PEEK 23685) to give the start of the Spectrum variables area. Change 16400 to 23684 and 16401 to 23685 in lines 120 and 150 also.) A number stored in 5-byte floating point notation has an exponent byte, which acts, as with the decimal E notation, to shift the binary point along to the correct place. The exponent value is stored as exponent plus 128, and can hence be negative or positive. It works in powers of two, and the value of this (exponent raised to the power of two) is given in the program. The representation of zero has a special form, such that the exponent is 0, and the values of all the other bytes is also zero. The value stored in the exponent byte is thus between 1 and 255, giving possible exponent values between - 127 and +127. The range of numbers covered 15 then what would be presented if our POWERS ОЕ TWO” program went on to 127 rather than just 16. The mantissa value (represented in the next four bytes) is converted to the numeric value by multiplying it by 2 raised to the power of the exponent: N - M*2*, where M is the mantissa value and e is the exponent (value stored in exponent byte less 128). This process can also be considered as moving the binary point the number of bits given by the exponent. The mantissa bytes are considered as a single sequence of binary digits, with the binary point at the beginning. The program gives the values stored in each byte (as with the “ЕГОАТ”” program), and then converts to binary to give the mantissa sequence. Since the first bit of the mantissa sequence is always 1 (the mantissa 1s always between .5 decimal and 1 decimal, but never reaches 1, i.e. 0.5< = m<1) the first bit 15 used as a зол bit. If the number is positive, the first bit is changed to Ø. If it is negative, the first bit is set to 1. This is used as a means of handling negative numbers, since all the numbers generated in the 346 floating point notation are positive, and an equivalent to the ‘ — ' sign is needed to show negation. Input 0.75 into the computer when prompted. The display will be like this: INPUT NUMBER NUMBER - 0.75 EXPONENT - 128 2**0-1 ( 4 on Spectrum) MANTISSA BYTES: 64 0 0 0 01000000 00000000 00000000 00000000 The evaluation is as follows. The first bit is a zero in the mantissa. This indicates a positive number. The first bit is changed to a 1, and the value of the mantissa is now .11000...0. The trailing zeros are ignored. Binary .11 is decimal 0.75 . The exponent value is 0, and 2 raised to the power 0 is 1. So we have a value of 0.75*1 = 0.75. If you input — 0.75, the display is identical except for the first mantissa byte ( + 128) because of the first bit now being 1, and the first mantissa bit, changed to 1 to indicate a negative number. This is left as 1, and evaluation then proceeds as before. Now input 3.75. The exponent is 130, 2**2 ( Жоп Spectrum) is 4, and the mantissa bits hold the sequence 01110... The first bit changes to 1, and this gives .1111 binary, 0.9375 decimal. 4*0.9375 = 3.75 . The alternative way of viewing the process is to consider the exponent as moving the binary point along. In this example, we have the sequence .1111, and since the exponent value is 2, the binary point moves the same number of places to the right, to give 11.11 , which is 3.75 in decimal. In the previous case, with 0.75, the exponent value was 0, so the point was not moved, and the bits were .11 . Negative exponents move the binary point to the left, adding zeros. The Spectrum has a special representation for integers in the range + 65535 to — 65535, in which the first byte (exponent byte) is zero, as is the fifth byte. The second byte acts as a sign byte, holding 0 if the number is positive, and 255 if the number is negative. The third and fourth byte hold the number (least significant byte first). You can use the **FIVEBYTE'' program to investigate this representation if you are using a Spectrum. To illustrate rounding errors and an otherwise puzzling aspect of the representation of numbers, input 1/2 into the ‘‘FIVEBYTE”’ program. We get exponent byte = 128, exponent 128 ~ 128 = 0, and a zero in the first bit. This changes to a 1, and we have .100.... Exponent Is zero, so we don't move the binary point and get .100...., which is 347 0.5, and equal to a half. Thus far all is well. If we like, we can consider that we got .100.... and multiplied it by zero to get our half. As we said above, the two processes are identical. But now input 0.5. This should be the same, but instead we get exponent equalling 127, and 0111....1 (thirty-one 1’s)! We seem to have an error. However it is a pretty small one, though it explains why the computer rounds its numbers. To avoid considering % as not equal to 0.5 it has to take into account the fact that the decimal to binary conversions have these inaccuracies. Binary addition of two 1’s causes a @ to be placed in that byte, and a 1 is placed in the next column to the left. (If you’re interested, the other rules for addition are: 1 and 0 give 1, 0 and 0 give 0, three ones (1, 1 and a carried 1) give 1, carry 1 to next column on the left. Try a few simple sums!) This means that if a 1 is added to the least significant bit of our sequence of ones: пека жа 1111 1 0 I. (carry) 0 1 (carry) 0 1 (саггу) etc all the 1's will become zeros, and the last carry would put 1 in the first bit, which would make it the same representation as the % sequence, but this also has a 1 in it. This forces a carry to a non-existent bit to the left of the mantissa. This gives us 1.0 as our binary, and the exponent shifts this (exponent = - 1) to .100...., which is correct. Or we сап consider this as 1.0 binary (1 decimal) multiplied by 2 ` '(0.5). So the error is in the least significant bit. The size of the error is thus 2~*’, the value of the right-hand 1. This is fairly small! The computer rounds numbers to ensure these inaccuracies do not cause errors. It considers numbers equal if the difference between them is less than a certain amount. Rounding errors can still build up under some circumstances, however, and it is important to note that no computer performs totally accurate arithmetic, except with integer values. You may be a little overwhelmed by numbers at this point, but before we give them a rest we should introduce you to another numbering system — Hexadecimal. This is another numbering system much used in computing, although it has no practical application for us at present since the 348 Hexadecimal system (often abbreviated to Hex) is primarily used in machine-code programming which is beyond the scope of this text. Whereas binary is base 2, and decimal base 10, hexadecimal is base 16. This is a convenient system for computers using 8-bit words, since 16 x 16 = 256. Any value which is held in a single byte can thus be represented by a two-digit hexadecimal code. The system uses the digits 0 to 9, and goes on with A, В, C, D, E and F, to represent the numbers 1 to 16. Here is how the system counts: Decimal Hexadecimal Ø 0 (9 x 164) 1 1 (1 ж 16°) 9 9 (9 x 16^) 10 A (10 x 164) 11 B CUL 167) 15 F (15 x 167) ó 16 10 ( 1 16.) +, ( Ø x 164) 17 11 Ci x15)4CI1x]l15 ) 25 19 (Tx 161) + C Ox 165) 26 1A lx 167) + (20 x 167) 31 lF (XX x 161) + #18 ш 160) 32 20 (o2 167). + í Өле 16”) 154 9A ( 9 x 161) + (10 x 164) 155 9B ( 9 x 167) + (11 = 18") 159 OF (ox 161) + (15 x 164) 16¢ AG (16 x 16) + (Ø x 16’) 250 FA (18% 16°) 4°16 x 167; 254 FE (15 x 161) + (14 x 165) 245 FF СІЗ «x 16°) = CS ж 167) As with any number system, we could go on (256 is 100 hex, etc.), but the use of hexadecimal is in representing binary numbers in a more convenient form than strings of 1’s and 075, which are difficult to read and easy to make mistakes with (unless you аге a computer’). The advantage of hexadecimal notation is that any 8-bit binary number is convertible to hex far more easily than into decimal, due to the relationship of base 2 and base 16 numbers. Base 16 is base 2*, and 349 this means the 8 bits of a byte can be divided into two sets of four bits (remember 1111 binary = 15 decimal = Е hex) and converted to the corresponding two hex digits. For example, the number 116 decimal is in binary 01110100. Split into two groups of four bits, 0111 and 0100, we convert each group to a hex digit. 0111 binary (7 decimal) is 7 hex 0100 binary (4 decimal) is 4 hex The number in hex is 74. Check this: (7 x 16) + (4x 16°) = 112+4= 116. Again, 93 decimal is 01011101 binary: 0101 binary (5 decimal) is 5 hex 1101 binary (13 decimal) is D hex The number in hex is 5D. (5 x 16) + (13 x 16°) = 80 + 13 = 93 To avoid possible confusion when both hexadecimal and binary numbers are being used, a small h should be used after a hexadecimal number. Our examples above would be 74h and 5Dh. Hex numbers are grouped in twos, and the leading zero should be used for numbers less than 16 decimal, so that 12 decimal should be written 0Ch, and not C or Ch. Similarly, numbers up to 65535 decimal (held in two bytes of binary), are representable with four hex digits. 11111111111111111 binary is thus FFFF hex, 10101101001101110 is 1010 (A)/1101 (0)/0011 (3)/1110 (E): AD3Eh. Work out the value of this in decimal. The program library has programs which convert decimal to hex and vice versa (“НЕХПЕС” and ‘‘DECHEX’’). Analyse these programs to see how they work. The CODE and CHR$ functions are used to check the hex notation, or produce it. Exercises 1 Alter the “СНКОМ” program to print just the large character, and then the inverse form next to it, by reversing the printing instructions for the character to be printed when a 0 or 1 is found in the binary form. 2 Using the “BIGPRINT” program as a basis, store the charac- ters of each line of the large characters in an array, so that a scroll routine can be used to cause the message to disappear off the top of the screen line by line, and re-appear at the bottom. 3 Write programs to store a string array above КАМТОР, and then retrieve it. Use a three-dimensional array. 350 PART FOUR APPLICATIONS PROGRAMS AND GAMES ш 3 ЖЕШСИН, Өре FIFAHSOOBS РИТА ЗА 23127. SECTION V: APPLICATIONS PROGRAMS V1: Programming for Applications You have been introduced to the full set of ZX81 BASIC instructions. Spectrum users have some additional instructions in the Spectrum superset of BASIC, but we have attempted to show how all necessary operations can be performed on the ZX81 and the Spectrum merely makes some operations easier to implement. We have covered a range of operations, involving loops, lists, array manipulation, sorting, subroutines etc., and the implementation of control structures. These are the raw material of programming. The combination of what you have learned about algorithms, design, program structures, manipulations and methods with the task you wish the computer to perform produces an applications program. There are no rules to derive algorithms. If there were, they could be coded into a master program that would write our programs for us! We have illustrated ways of thinking about a problem that can help, but each program we wish to write presents a unique problem. Familiarity with the language and control structures, and with existing solutions to a variety of problems, either other people’s or your own, make it easier to program. As with most things, the art and craft of programming becomes easier with practice. The importance of keeping notes about programs you have written, and on solutions to problems you have found in analysing other programs, is that it will prevent you re- inventing the wheel. As you write more programs for yourself, you will find that you come to recognise the method (or methods - there is seldom only one way to perform a given task!) by which you can implement and code each module of your program. Modular, structured program design methods help to break down a programming problem to these recognisable chunks, and you wil recognise more aspects of a problem as having been met (and solved!) before as you gain experience. You will also become familiar with the types of data structure required in a program to make it possible to manipulate the data efficiently, and grasp more quickly and clearly that, for example, a given set of data is more efficiently (i.e. easily) handled in a multi- dimensional array than in separate lists, or that a similar routine in different program modules could be handled by a single subroutine if suitable variables were initialised before calling the subroutine. Experience cannot be transferred, and there is no substitute for practice, but examples can be given. After the important topic of writing user-friendly programs has been dealt with in the next Unit, we give examples of programs written to perform specific tasks, to illustrate the process of designing applications programs. Games programming is briefly dealt with in the following Units, since games 393 are a good testing ground for problem-solving and programming techniques. V2: Instructions and Input Checks If you have written your own program, you know which inputs the program requires, in what form and when. You know, for example, that when ‘‘ANOTHER СО?” appears on the screen, you must press the Y key to run the program again. Now consider what happens if someone else wishes to use the program (or if you return to it after some weeks). There is not enough information available to the user. The term user-friendly is applied to programs which have sufficiently clear and precise instructions to tell someone who has never seen the program running exactly what to do. We should always attempt to make our programs at least reasonably user-friendly. To continue the example of running a program again, the line: 60 PRINT “AGAIN?” could be followed by 70 INPUT A$ 80 RUN or 70 IFINKEY$ =" " THEN GOTO 70 80 RUN Or 70 IFINKEY$-'''' THEN GOTO 70 80 IF INKEY$ =" Y" THEN RUN or 70 PAUSE 40000 90 RUN These need different responses. We should use for the first “PRESS NEWLINE (ENTER) TO RUN AGAIN”, for the second and fourth "HIT ANY KEY TO RUN AGAIN”, for the third “AGAIN? (PRESS Y OR М)” or similar instructions appropriate to the program. We can assume that the user recognises that an input prompt requires string or numeric input, according to its form, but (as we shall see later) there may be reasons for requesting a number in string form, and in any case we must make it clear what is required. We should be careful to use, for example: “INPUT FIRST WORD" andnot “INPUT AS" "ENTERA NUMBER 1 ТО 10° andnot “INPUT X” "MONTH (1 TO 12)" апа not “MONTH?” since if the user does not know what A or A§ are in the context of the program he or she is unlikely to respond correctly, and might try entering JAN or MARCH for the month. We should also avoid the use of instructions grouped together: 10 PRINT “INPUT CURRENT, P.D, KNOWN AND UNKNOWN RESISTOR”’ 394 20 ІМРОТА 30 INPUT B 40 INPUT C 30 INPUT D 14 DIM A(10,3) 20 PRINT “INPUT MATRIX” 30 FOR F= 1 TO 10 40 FOR N= 1TO3 50 INPUT A(F,N) 60 NEXT N 7/0 NEXTF It is very easy for the user to forget which of the inputs is currently required. The information also fails to include the units of the values required, and does not print the input values on the screen. We should use a format like this: 10 PRINT “INPUT CURRENT IN AMPS” 20 INPUT A 30 PRINT “CURRENT = '; A“ AMPS” 49 PRINT “INPUT P.D. IN VOLTS” 50 INPUT B 00 PRINT "Р.О = “ Be" мо" This provides both clear instructions and visible input values. A look at any reasonably complex user-friendly program will show you that a significant portion of any application program is instructions. Instructions should be concise, but only to a degree that still provides adequate information. Expanded instructions can form part of the documentation of a program, but the program itself must contain the basic instructions required to ensure correct input and manipulation. The program ‘‘MATMULT”’ in the program library has a better approach to the array entry problem. Try to write one yourself, then compare the two routines. The combination of good instructions and input checks is the best method of reducing user error. The human being is less reliable than the computer, and far more inaccurate results or program crashes occur due to input error than happen due to bugs in the program, assuming it has successfully completed a sequence of dry runs. Checks to reduce the possibility of human error, or prevent bad effects from it, are the means by which a program is ‘idiot-proofed’ or ‘mug-trapped’. Commercial programs designed for inexperienced users with no programming knowledge often have as much space devoted to input checks as to the program proper. We can assume some awareness in the users of our programs, and trust that they will enter 2 and not TWO, for example, but check routines can ensure that simple keyboard errors are not passed over. Subtle errors or straightforward mistakes are less easy to deal with. 3935 It is a simple matter to check that an entered value is within an acceptable range: 10 PRINT “INPUT MONTH (1 TO 12)" 20 INPUTM 30 IF M>12 OR M«1 THEN GOTO 10 Since the month is to be input as an integer we could add a line to check this: 40 IF INT M<>M THEN GOTO 16 In fact one line will do it all: 30 IF INT M<>M OR М>12 OR М<1 THEN GOTO 10 Note that if there is an error, using GOTO 10 rather than GOTO 20 at least indicates to the user that something has happened by re-printing “INPUT MONTH (1 TO 12)” on the screen. If we used GOTO 20 the user would wonder what had happened, and maybe think that the year was now required. It is better to have a statement specifically stating that there was an error in input. To continue our example, we could have these lines: 30 IFINTM-M AND М< = 12 AND M» = 1 THEN GOTO 60 40 PRINT “INPUT ERROR:RE-INPUT MONTH' 50 GOTO 20 60 PRINT ''INPUT YEAR (AS 82 FOR 1982, ЕТС.)” ‘errr (Rest of program) The user is informed what is wrong, and told what to do. Make sure you see why the new line 30 had to have both the relational and logical operators switched round to make the program work. To enable re-use of check or error routines it is convenient to place them in subroutines. The following date entry routine uses a subroutine to print an error message for a few seconds (line 500) which is used if any of the checks shows an error. The routine checks the following: i) Day of month between 1 and 31 (line 40) ii) Month between 1 and 12 (line 90) ш) Year between 1911 and 1998 (line 140) iv) Whether the year is a leap year, and if it is not, that 29 February has not been entered (line 190) v) That days which do not exist in some months have not been entered (line 210). Check the logic used in these lines to see how it works. The lines are good examples of how multiple conditions can be combined, but for that reason they are a little difficult to follow. 10 PRINT “ENTER DATE" 20 PRINT "DAY?" 38 INPUT D 40 IF D»-1 AND 0<=31 THEN GOTO 70 58 GOSUB 500 68 GOTO 20 70 PRINT “MONTH? (1 TO 12)" 88 INPUT M 356 90 IF М>-1 AND M<=12 THEN GOTO 120 100 GOSUB 500 110 GOTO 70 120 PRINT "YEAR? (AS LAST 2 DIG 115)" 130 INPUT Y 140 IF Ү>10 AND Y<99 THEN GOTO 170 150 GOSUB 500 160 СОТО 120 170 REM *CHECK DAY US MONTH* 180 REM *LEAP YEAR* 190 IF INT (Y+1900) /4) <> (ү+190 0) /4 AND М-2 AND D=29 THEN GOTO 220 200 REM *SHORT MONTHS* 210 IF NOT ((M=2 AND D>29) OR ( M=4 OR M=6 OR M=9 OR M=11 A ND D= 31) THEN GOTO 240 220 GOSUB 500 238 GOTO 19 240 REM .....PROGRAM 250 PRINT D;"/";M;"/19";Y 268 REM seoses 278 REM «se cue 400 GOTO 999 499 REM **ERROR NOTICE** 500 PRINT "***INPUT ERROR***"," PLEASE FOLLOW INSTRUCTIONS" , RE-INPUT REQUESTED DATA". 510 PAUSE 200 520 CLS 530 RETURN 999 REM*END* The program ‘‘INDATE”’ in the program library uses much the same routines, but set up as two nested subroutines, so that it can be used in any program requiring multiple date entries, such as an accounting program. It is also a simple matter to put in input checks that print the input, and invite the operator to check if it is correct, and to re-input if an error has been made. This is important where multiple data entries are being made, since an error would otherwise require entering everything again. As an example, here is a check routine for string input: 40 FOR N = 1 TO X 50 PRINT "INPUT STRING";N 60 INPUT WŠ (N) 70 PRINT W$ (N) 80 PRINT "IF INCORRECT PRESS E TO RE-ENTER."; TAB 0; "PRES S ANY OTHER KEY TO CONTINUE IF OK." 99 IF INKEYS -"" THEN GOTO 99 100 IF ІМКЕҮ5 = "E" THEN GOTO 5 0 110 NEXT М 397 Rather than check each value, it is sometimes better to wait until all entries have been made, and then print them out for checking. This routine does this for a list of numbers: 10 REM INPUT SPRINT» СНЕСЕ AND C ОРЕЕСТ ROUTINE FOR LIST 20 190 200 210 220 PRINT “ENTER NUMBERS" DIM ACz4) FOR L=i TO 24 INFLUIT ACL) PRINT AT 3+L-12*(L312)510%( (2199? АС 230 NEXT L 200 FRINT АТ 21:07 "ALL CORRECT? CY ПЕ М3" 210 INFUT ES 320 IF E$z"Y" THEN GOTO 1000 330 CLS 340 PRINT "EACH VALUE WILL EE F FAINTED"; "ENTER NEWLINE IF ik. NEW VALJE", " IF WRONG, " 350 22,0 1000 ЕПЕ Ғ-1 TO 24 FEINT АТ 21,;07ACF3) INFUT N$ IF N$z"" THEN GOTO 410 LET ACF3= VAL N$ FEINT АТ 21sO07ACF3;3" SCROLL NEXT F REM *REZT OF FROGRAM* Spectrum users should delete line 410, inserting 410 POKE 23692, - 1. The virtue of using string input is that instead of stopping the program with an error message if an invalid entry is made (a letter, character that is non-numeric, or more than one decimal point), as occurs with a numeric input, the string input can be accepted whatever the characters input. The inputted string must be checked, however, or else we just get an error message when using VAL to convert to a numeric value. This requires a routine like the following: REM "STRINGNUM" PRINT AT 0,5; "ІМРОТ NUMBER" INPUT NŠ LET DP=0 IF NS="" ‘THEN GOTO 100 FOR Е=1 TO LEN NS IF CODE N$(F)«27 OR CODE NŠ (F)>37 THEN GOTO 100 IF CODE N$(F)-27 THEN LET D P=DP+1 NEXT F IF DP>=2 THEN GOTO 100 GOTO 130 PRINT AT 0,5;"ERROR IN INPU {н PAUSE 75 СОТО 1@ REM ...REST OF PROGRAM.... SCROLL 358 150 PRINT VAL NŠ 168 GOTO 10 Spectrum users need to change the character code checks in lines 60 and 70. Change 27 in line 70 to 46. Change line 60 to read IF CODE N$<46 OR CODE N$ = 47 OR CODE N$>57 THEN GOTO 100. Change line 140 to read 140РОКЕ 23692, — 1 and line 150 to read 150 PRINT АТ 21,6;VALN$. Line 20 inputs the string. Line 30 sets a variable to store the number of decimal points. Line 40 checks that NEWLINE (ENTER) alone was not pressed, and passes control to line 100 to print an error message if it was. Lines 50 and 80 set a loop for the number of characters in N$, and line 60 uses CODE to check whether characters other than numbers and the decimal point are present, and goes to 100 for an error message if they are. Line 70 adds 1 to the variable DP for each decimal point found in N$. After the loop, line 90 sends control to 100 for an error message if there is more than one decimal point. Line 95 bypasses the error routine, and line 150 uses VAL to return the number for printing. At this point, if the number were needed for calculation, a variable could be set (LET N = VAL N$) to store the value. Note that an input error causes (line 120) the input routine to be repeated, after indicating for 1% seconds that an error exists. V3: Example Programs This Unit presents some examples of applications programs of various types, as follows: 1 “КЕАСТ”: Reaction time testing. 2 *BINGO'': Creation, calling and checking the cards for playing Bingo on the computer. 3 “REF. INDEX”: The calculation of refractive indices from the angle of deviation and prism angle data produced by spectrometer experiments. 4 “SERIES”: The summing of a convergent series to a given degree of accuracy. 5 “СКАРН”: Calculation and plotting of functions, with titles and scales, to give a hard-copy printout. 6 “ELEMENT”: The calculation of empirical chemical formulae from the percentage composition of compounds, or the percentage composition from the numbers of atoms of each element in the molecule. 7 ‘*CASSFILE’’: Cassette file storage and manipulation, with printout of cassette files and cassette label printing. None of these programs are particularly complex (although CASSFILE is lengthy), and they deal with fairly straightforward applications. However, the principles involved are valid for any size of program, and 359 the programs themselves demonstrate many of the techniques and procedures introduced earlier in the text. More examples of applications programs and useful subroutines are to be found in the program library provided in the Appendix, but they are not as fully annotated. The programs here are presented as problems and solutions, with some discussion of the approach to the problem. The procedure is then presented, and the derived program. Please remember that any program can be written in different ways, even given that the algorithm is exactly the same. This variety of solutions means that there is never only one correct program. Spectrum users should note that we have indicated some instances where the additional functions of the Spectrum can be put to use. These functions are described in the next Section. After you have explored the new functions, you should return to these programs and modify them for practice in the use of these facilities. 1. “REACT” Problem: To use the computer to assess response times in reaction to a signal. An average should be taken of a number of timings. Research the problem: The timing function can use the system variable FRAMES. A start signal will be required, which should be preceded by a random delay to prevent anticipation. Computing time must be allowed for in the result. The number of timings desired should be input and used to set up a loop. On the ZX81 FRAMES is a system variable held in 2 bytes, 16436 and 16437. On the Spectrum it is 3 bytes, 23672, 23673 and 23674. The program can use both bytes on the ZX81 and the two less significant bytes (the first two) on the Spectrum (since we do not need to time hours!) This will give a timing period of up to ((256 x 255) 255)/50 seconds in the U.K. and ((256 x 255) + 255)/60 seconds in the U.S., or about 22 and 18 minutes respectively, before the FRAMES counter, which counts backwards by decrementing by 1 every 1/50 (or 1/60) seconds, reaches zero. This will allow the program to be used as a timer for longer periods, or modified for use as a stopwatch program. Procedure: The program will have a loop structure, determined by the input of the number of tests required. Outside this loop will be the instructions at the beginning of the program, and the output of average reaction time. This timing module is the core of the program. The input module (instructions, ‘get ready’ messages and an input for the number of timings required) and the output module (average time) are easily built around this. We may proceed to code in a version of this module, having decided our structure for the program, and test/debug the timing module, before using the editing facilities to modify this module as required and code in the input and output modules. 360 The timing module will require the address bytes to be set at a known value (the maximum, 255) by POKEing values in, and the values returned by PEEKing these bytes will be used to calculate the time according to the expression T -((256*(255 - PEEK 16437)) 4 255 - PEEK 16436)/50. (U.S. users must use 60, not 50 in the expression and the program.) For the Spectrum the first address will be 23673 and the second 23672. Our procedure in this simple linear program is as follows: 1 Input Module = 1 Give instructions 2 Input number of tests required (A) 3 Initialise array for timings, B(A) 4 [Initialise variable for total timings, X 5 Initialise FOR - NEXT Loop (1 TO A) Ш фа 2 Timing Module Give “рес ready’’ message 2 Provide random delay to prevent antici- pation 3 Set timing function by POKEing 255 into the FRAMES addresses 4 Give signal 5 Walt for key to be pressed 6 Calculate reaction time. Allow for computing time 7 Store result as B(A) 8 Add B(A) to X 9 Repeat 1-8, A times 3 Output Module = 1 Calculate average reaction time Print average time The timing module could be coded, run and tested as follows: Timing Module Program Listing 1 REM REACT CORE FROGRAM 120 PRINT "-ON YOUR MARKZ-" 170 PAUSE 75 120 CL 190 PRINT “ GO N н 2.2 Allow interruption by player 3.1 Display players’ numbers 3.2 Display numbers called 3.3 Check winning card 1.1 These are the instructions needed to start the game. At each stage in the program it is essential to give clear directions to the user on how to proceed. 1.2 ‘The caller's numbers require a random list of the integers 1 to 99 (each number occurring only once) which will be put in array А(99). 366 1.3 The players` cards require 4 sets (cards) of 15 random integers in the range 1 to 99 (i.e. different numbers). The cards should have an ordered list of numbers and each list is a different set of numbers. These will be put into arrays O(15), R(15), S(15) and T(15). Display the players’ cards on the screen and allow time for the players to take down the numbers. Display the caller’s numbers one at a time on the screen in large form. Allow the display to be interrupted when a player calls ‘house’ (i.e. thinks that all the numbers on his card have been displayed). Repeats 1.4 for players to check their numbers. The numbers called (i.e. those actually displayed in 2.1) are sorted into numerical order (and put into array P(99) which contains between 15 and 99 numbers) and displayed on screen. The ‘winning’ card is selected and the numbers on this card are put into the array V(15). These numbers are then compared with the numbers called [in P(99)] to check that they are correct. Algorithm Description 1.1 This section gives the minimum instructions required to play. You may want to key in fuller details of the game of BINGO. (Lines 10 to 110 in program). 1.2 Set up caller's numbers Flowchart: INITIALISE ARRAY This routine starts at line 120, clearing the screen and going into fast mode on the ZX81 for the calculation. The above routine is contained within the caller's numbers subroutine (lines 2500 to 2590), but note this could be a subprogram sequence as part of the main program as it Is only executed once. 1.3 Setting up (the BINGO cards) Flowchart: DIMENSION ARRAYS FOR EACH NUMBER ALREADY CHOSEN 368 FOR EACH CARD FOR 15 NUMBERS LET Y = @ GOSUB SORT GOSUB ARRAY CHOICE In the program this routine begins at line 320. Note array P(99), which is used in the sorting routine (although containing only 15 numbers) and is then used again later for the caller’s numbers. Lines 480 - 540 carry out the selection of the 15 random numbers. Subroutine 3000 — 3170 is the sorting routine which is the SHELL SORT given in Section T. (A fast sort is needed as at a later stage we are sorting nearly 100 numbers.) Subroutine 3500 — 3560 puts the numbers into the appropriate array. 1.4 This subroutine (lines 1600 - 1650) displays the numbers on the cards in a tabular form. 2.1/2.2 Display caller’s numbers and interrupt if ‘House’ is called оо O2 М mi З.А This subroutine takes numbers generated апа (in FAST mode оп the ZX81) displays them 16 times their normal size and places them in an array P. Variable Z counts the number of numbers called. At the end of this subroutine the numbers called have been put into the array P (which will contain Z numbers). This repeats step 1.4. This routine (lines 960 — 1070) calls a sort subroutine at line 3000 which sorts the list P (Z) into numerical order and prints them out on the screen. This subroutine (lines 4000 — 4260) has two parts. (1) Select the ‘winning’ card and arrange for the ‘winning’ list of numbers to be put in the array V(15) (lines 4000 - 4120) (2) Check the numbers on the ‘winning’ card. It is necessary to search the ordered list P containing Z numbers for the numbers in the ordered list V containing 15 numbers. If any number is missing the card is not complete. If all numbers are present then CONGRATULATIONS is printed. The quickest search method is as follows: Search for V(1) in list P until it is found, say P(12). Search for V(2) in list P beginning at P(13) etc. The search will end as soon as a number in list V is not in list P but will continue for all 15 numbers in list V if they appear in list P. The flowchart for this search is as given below: 370 COUNTER FOR LIST P N=] COUNTER FOR N>15 LIST ү PRI V(N) CORRECT LET M = M+] CHECKS IF NUMBERS IN LIST.P FINISHED COMPLETE RETURN E 2 TO GAME PRINT СОМСААТ- ULATIONS STOP 371 Data Table The following variables are used: Q(15), R(15), S(15), T(15) are the arrays containing the players numbers. A(99) is the array containing the numbers for the caller. P(99) is the array containing the numbers actually called, and is also used as a temporary storage in setting up the players’ numbers and in the sorting routine. X is a random number between 1 and 99. Z is a counter for numbers called. Y is the number of elements present in an array to be sorted. V(15) is array containing ‘winning’ list of numbers. B$(99,2) is an array containing the string values corresponding to the elements in P(99). C is the character code of second character in element of array B$. D is the character code of first character in element of array B$. M is the counter for array P in the ‘check numbers’ section. Comments: If you wish to play with your own BINGO cards and let the computer be the caller only, then you can delete modules of the program as follows: 1.3 Set up players’ numbers 1.4 Display players' numbers 3.1 Display players’ numbers These latter two modules are the same subroutine. You could also revise the program and include, as an option in the user instructions routine at the beginning, the choice of the two different modes of play. Spectrum modifications: Delete Lines 290 and 585. Change Line 660 to 660 PAUSE 0 Delete Line 830 Change line 800 to 800 FOR F = 1 TO 400 Edit line 810, renumber as line 805, to read 805 IF INKEYS$«»'' ”’ THEN GOTO 830 New line 810 NEXT F Note: This sets up a FOR - NEXT loop to contain the reading of INKEYS, to make this operation of checking to see if someone's bingo card is full more reliable. The delay of a 1 TO 400 loop is about two seconds, the same as the PAUSE in the original program. Edit line 835, renumber as line 830, to read 830 CLS Delete line 835 Change line 980 to PAUSE 0 Delete line 1005 Delete line 1025 Delete line 5010 372 Change line 5070 to 5070 LET E = PEEK (15360 +8*C +R) Change line 5200 to 5200 LET Е = PEEK (15360 +8*D +R) Flowchart ‘BINGO’ START PRINT INSTRUCT- IONS PAUSE PRINT NUMBERS CALLED PAUSE STOP SELECT NUMBERS GOSUB BIG PRINT BINGO CALLED 212 Program Listing 2 GEM SS NGO” 10 REM RRR KR ХХХ OY HERE %1, 36% INSTRUCTIONS % XX 3e XXE EE ЖЖЖ ЗРЗЕ ЭЗЕ 20 PRINT TAB 10; "BINGO": TAE : ох ыы 30 PRINT |+ É "SOUR EINGO CARDS A RE PRODUCED" 40. PRINT 99 "А5 THE LISTS "" WQ ни 4 ип A пи ' ы" Өт ТЕГ] AND "H" n T пи и 20 PRINT »+"THEY ARE СОСОРТЕП 71) А PRINTER" ++, "TF CONNECTED, OTHE RWISE YOU MUST" 60 PRINT so "NOTE DOWN YOUR CHO SEN LIST WHEN" 70 PRINT |+ + "THEY АРРЕАР, NOTE T HE LETTER ALSO” ШО PRINT »% “WHEN YOL ARE READY FRESS ANY KEY" 70 PRINT || "TO START. THERE WIL L BE A DELAY" 100 PRINT |, "WHILST THE NUMBERS ARE SET UP," 110 IF INKEY$ ="" THEN GOTO 110 120 CLS 200 RAND 290 FAST 200 REM 33433 C HHH Ж *1; Z«*SET UP CALLERS x * NUMEE Fs: x Хх ЖҰ Ж 210 DOSJE 2500 320 REM 3J4333X34X3 3 € 3€ (XC C969 3 3 X. *1.cXSET UP PLAYERS * * NUMBERS * 3X 3C 3C 3C3C 33€ 3E 3€ 3E KH 553 420 DIM acis) 430 DIM Есі) 440 DIM 5(1©®) 450 DIM Tc183 4640 DIM P(9?93 470 ЕСЕ W=1 TO 4 430 FOR J=1 TO 15 490 LET X= INT (7 500 FOR Isi TO J-1 510 IF XzsP(I2 THEN GOTO 490 220 NEXT I S90 LET PGJ»zX 540 NEXT . 550 LET Y=15 ESO GÜSLE 3000 570 DOSIJE 3500 280 NEXT U seo SLOW S70 PRINT 600 FRINT 610 REM XXX 33333 33 M EE 364396 #1, 48 DISPLAY PLAYERS ж ж NLIMBES ж ХХХ DOSJE 1600 DG. э LI e 374 & 30 640 850 REM **L IST COPIED IF жж жж PRINTER жж COPY PRINT »» "PRESS ANY KEY TO F ROCEED" EGO 670 650 THE EPO 700 IF INKEY$ ="" THEN GOTO 660 DLE PRINT "THE CALLER WILL GIVE NUMEERS ONE AT A TIME" FRINT PRINT "WHEN YOUR CARD 15 cU MPLETE PRESSANY KEY WHEN NUMBER IS ON SCREEN" 710 720 CEED" 730 732 740 745 720 755 760 PRINT PRINT “PRESS ANY KEY TO РЕС) IF ІМКЕҮФ ="" THEN GOTO 730 CLS REM 3333 3 3 X X X € ЗЕ M +2. 1% PRINT OUT CALLS x HHH HH HHH EE EE EE HE LET Z=1 DIM Beers, 2) CLS PRINT " PRESS ANY SEY WHEN YOUR CARD IS COMPLETE” 770 750 790 793 200 210 =O я Е CS du 220 S20 [жа есі = 240 S50 EINE ЖЫ S40 270 2120) 890 200 910 920 730 935 940 745 250 ЕКПЕ N=Z TÜ 99 Güzim] Sooo LET FCN) =ACND PAL'SE 200 REM 33 3 3 9€ 303€ 9€ 3€ 9€ 30 3€ 3E 3E 3E CE CE E #2. Z2XPLAYER INTERRUPT ж HH 3CCC JC 3C Хы IF INKEY$ <> "" THEN GOTO & LET Z=Z+1 NEXT N LW | L LZ FOR N=1 TO 10 PRINT ТАБ N:"Z«*BINGUÜUS-ZXEIN NEXT N PRINT Өз “CHECK YOUR CARDS" REM 3C 3C 36 36 3: 3€ 3€ 9€ 9€ C Хы Ж яз, 1*DISFLAY PLAYERS ж * NLIM RER © % ХХХ РАЦЕ 100 LET Y=Z PRINT “YOUR NUMBERS WERE" PEINT REM X33534 3333333 M EE SE ARERR ЖРБІМТ QUT CARE NUMBERS + GIJE 1600 FEM FEM жж Хы 3E 9C ы Ж X. ZXDISPLAY NUMBERS ж * CALLED * Y X 3C 3€ 3C CC 555555553553 375 260 PRINT “PRESS ANY X БҰ TO GET LIST ОЕ", "THE NUMBERS CALLED. " 1270 PRINT "THERE WILL ре А SHOP: T DELAY FOR SORTING, " 9780 IF INKEYS ="" THEN GOTO F20 we cl © 1008 FART 1010 pne zi oc 1020 ELS TOFS SLOW 1030 PRINT "CALLERS LIST" 1040 PRINT 1050 FOR Nel TO Z 1060 PRINT РМ" "3 1070 NEXT N 1050 PRINT LOSE REM HREM ERR EER EE HEH REALE EH #3. JW CHECK WINNING X ж MARI * XE 3 XXX XC ЖЖ 1070 GÜSLUE 4000 1100 LET 2=2+1 1110 PRINT ++ "DO YOU WISH TO CON TINUE THE GAME? CY/N3" 1420 INFET CS 1120 IF C#="N" THEN STOP 1140 IF Ce="¥" THEN GOTO 755 4450 PRINT "INPUT Y OR N ОМЕР. FASE" 1160 GOTO 1120 11920 REM J3XX33 0 (4 0 Хы ж END PROGRAM x X XC 34 АЕ 3E EXC OE EXE EE EEK at 1200 STOF 1210 КЕМ | EDO REM жұ АЖ x SURO TT NES ж ХЕҰ XE COE Ж 15920 КЕМ AOG Б ЕМ ж EXE CE EE EK EH ЖЖСӘМБЕЕПШТІМЕ TO PRINT ж AOUT PLAYERS CARLS + HH HHH HE HE EE EE 6 “410 PRINT "Ga": TAB 6: "8S"? ТАР і ев: TAB Ter *t* 4620 FOR ті TO 45 2420 PRI NT Gc.5; TAE &G:RCZo0: ТАЕ iz:m620: TAB Ler Сш 1440 NEXT 4 TESO RETURN 1660 REM жж МОЛ жж Хх ЖЖЖ ы 2470 REM SIO) БЕМ eM HE EH #*#¥5UCREOUTINE TO SET жж XXCALLERS NUMEBERZ Xx FEE ЖЖ EEE того DIM ACHD) 2240 FOR Net TO PP 376 ore as. 2520 2570 2580 2590 29850 S000 2010 32030 2040 S080 S060 3070 TOSO S070 3100 3110 2120 2120 2140 3150 21680 2190 3470 2500 3510 3220 3530 t ul el 3540 3550 3&0 3870 4000 4010 4020 зуу IF ACX) <> 0 THEN SOTO 2550 LET АсХ>= NEXT N ЕЕТМЕМ LET X= INT (99% RND 2-1 М REM жж ENDHI X% X33 ЕЕЕ HR KEKE XXE CX КЕМ 303 3 9 0 € CE HHH HH Ж X*SORT SUBROUTINE жж ж Ж ХХ LET S= LET S= INT (S/2) IF Š >= 1 THEN GOTO 2050 GOTO 3170 FOR К=1 TO Š FOR AsK TO Y-S STEP K LET E=A LET TsP(A«2) IF T >= РСВ) THEN GOTO 2130 г (ЕТ Ве-В-< IF В >= 1 THEN GOTO 3090 LET P(B+S)=T GOTO 23010 RETURN REM жж ENDSUE + HHH HH RIK REE ЕЕ ЭЕ ЗЕ KRK REM fet LF ХХХ EE 3C YE S## 5G ROUTINE FoR КОМБ» 23 NUMBER ARRAYS жж JC X- 3€ 3C 3€ 3C 3€ 263 3 3E ЭРЭР 36 3E 3E HEH EHH EE 1 70:12 2/7 BL IF Ше1 THEN LET ос) =Р CJ) TF Uz2 THEN LET--R(Jy=P (J) IF Нез THEN LET SCAOD PCI IF l4 THEN LET Tc PG) RETURN REM жж ENDSUE жж He KE SEE FEE EEE EEE EE E REM REMO ж ЖҰ ы ЖЖСШИБЕПИТІМЕ TO CHECK ae HX RESULTS жж 363 4C 3C 3E JC XC 3C 3€ 0E ыж PRINT [REM 3 Xx 3C Ж ee OMO #3. 3. IX SELECT WINNING ж ж CART є HHH X3 HHH HH HH MOORE MOYO PRINT "ТҮЗЕ WINNING CARD (È T3 it 377 4020 INFUT АФ £040 IF AS <> "QU AND AS <> "m" AND АФ <> "S" AND AS <> "T" THEN GOTO 4020 4050 CLS 4060 DIM Vct&) 4070 FOF N=1 TO 1% 4080 IF Ag="h" THEN LET V(N)=m (N 3 4090 IF АФ=" 8" THEN LET VCNI=SRCN 3 4100 IF Ag="5" THEN LET V(N)=S (N E 4110 IF A$z"T" THEN LET V(N)3=T (N ) 4120 NEXT N 4195 REM хх 3XX XXX XC XXE #3, 2. ZXCHECK NUMBERS ж 522222552222 52222 EY 4130 LET М1 4140 FoR Nzi To 15 4150 IF V(N)=F(M) THEN PRINT VON Jj?" QURRECT” 4160 IF VCNI=SFP CM) THEN GOTO 4200 4170 LET M=M+1 4120 IF M=Z+1 THEN GOTO 4220 4170 GOTO 4150 4200 NEXT М 4210 GOTO 4245 4220 PRINT “#CARD "FAG?" NOT COM PLETED»" 4230 PRINT МОМ)?" NOT CALLED" 42552 REM XGÜTO RETURN TO CONTINUE 4240 GOTO 4260 4245 PRINT »» TAB 47" жж CONGRAT ULATIONS жж "; TAE 45 "%%%%%%%%%% %%%%%%%%%"... "GAME ENDED. USE RUN TO RESTART" 4250 REM жж GOTO PROGRAM END жж 4255 GOTO 1200 4260 RETURN 4270 КЕМ жж ЕМПЕМЕ жж JC OC XC 3C JEFE AE 3C 3C ЭЕ ЭЕ ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ XE 4900 FEM SOOO REM ххх x * x X X HEH Хы HE *#*#SUBROUTINE GIG PFLOT** ee Ж 2010 FAST 2020 LET Е%(Мо- STR ACN? 5030 LET C= CODE БФ(М2(1 TO 1) 5040 IF LEN ЕФ‹М)© 7 THEN Goto 50 eo 378 5050 =060 5070 5020 2090 2100 5110 214 2160 2170 5150 2190 = 200 5216 =. » а ` а а 2220 “2840 s dad 2250 т270 есес 5290 “Ооо AGIO A020 GOTS z QAQ ë GS ё 872 С ) 5070 3. “REF. INDEX" Problem: In a laboratory experiment with a spectrometer, a series of measurements are made of the prism angle A and the angle of minimum deviation D for various prisms. The refractive index of each LET D= CODE E$CN» (2 TO 2) FOR R-O TO 7 LET E= PEEK (7680+8xC+R) БЕТ W= 125 FOR б=0 TO 7 IF E WO NH = 3 Output оо шо бо бо м м + O39 м = O оо + 52 GO OO GO OO OO — ка (O Со SIO 0 =< 4 Correct 380 Error 4.2 Return Subroutine Note: Subroutine called after each input. All entries can be re-input if Incorrect. See program listing. Data Table Prism number A(6,4) Four Angles of measurement for each of 6 prisms D(6,4) Minimum Deviations, for each value of A(6,4) N(6,4) Results of refractive index calculation for each experiment, derived from the values stored in arrays A and D Variable to store totals of minimum deviations. Average refractive index for each prism, from the average of the four values stored in array N. Used as loop variables for input Used as loop variables for printout Used as input for error check subroutine. Null string if incorrect, ‘‘C’’ if correct. START DIMENSION Flowchart “REF. INDEX ARRAYS OUTPUT RESULTS STOP INPUT PRISM NUMBER 381 INPU CORRECT CONVERT TO RADIANS CALCULATE R.I., ADD TO Z es No INPUT Yes PRISM CORRECT =ø No M = ] CALCULATE AVERAGE R.I, FOR PRISM 382 Program Listing = REM "REF. INDEX" 10 PRINT "**xREFEACTIVE INDEX3* "soo “USING SPECTROMETER" 20 PRINT ss "ALLOWS UP TO & PRI SMS AND 4 SETS OF READINGS FOR E 25 REM *-*AVGE REF. IND. AEEAY** 30 DIM Z¢4) 35 REM **FFISMS ARRAY ** 40 DIM Fé) 45 REM ##*#FRISM ANGLE ARRAY *#* 50 DIM Ас 4) 59 REM ##*#MIN. DEV. ARRAY** 60 DIM П(6з49 ес REM ЖҰРЕҒ. IND. ARR AY** 70 DIM N(65 43 SO FEM жж ХЕ ЕЖ 85 REM **INFUT DATA LOOF#+* 90 FOR N=1 TO é 100 LET 2-0 110 PRINT "INPUT PRISM NUMBER» I МРОТ 0", "ТО FINISH" 120 INFUT P (N) 130 PRINT "PRISM NUMBER ";P (N) 140 GOSLIB 700 150 IF A$ <> "C" THEN GOTO 110 160 IF F'(N)=O THEN GOTO 500 165% REM J3HuUdciads €x ХЫ + X*START READINGS 100Ржж 170 FüR M=1 TO 4 180 PRINT "INFUT FRIZM ANGLE IN DEGREES: INFUT Ó TO FINISH" 190 INFUT АСМ» M) | 200 PRINT "ANGLE OF PRISM "АСМ M) 710 GŪSIE 700 220 IF A$ <> "C" THEN GOTO 180 220 IF ACNsM)=0 THEN GOTO 410 240 PRINT “INPUT MIN. DEV. IN DE GREES" 250 INFUT DCN: М) 260 PRINT "MIN. DEV. ";D(Ns M) 270 GOSUE 700 280 IF А% <> "C" ТНЕМ БОТП 180 290 REM жжСПМУЕЕТ DEGREES Тож xxFEADIANZ жж 300 LET А=АсМ, М) + PI /180 310 LET D=DCNsM)* РІ /180 220 REM *#REFRACTIVE INDEXs* 230 LET М(МЭМо-( SIN ¢¢CAtD9/23 3 / SIN (6/2) 340 LET МСМ. М) = INT CLOOO#NCNSM 2%, 33/1000 250 LET Z=Z+N(N; М) 360 NEXT М 270 REM ##END READINGS LOOP жж ХХХ Жы 330 REM 390 REM жжАУЕРАСЕ TO 2 DEC. ++ ++ PLACES ++ 383 400 REM 410 LET Z=Z/(M-13 420 LET 7(Мо- INT (100%7-,52/10 Ü 430 NEXT N 440 REM 450 REM *#*ЕМП INFUT LOOP ++ 460 REM >> X X3 (€ 3€ 470 REM 450 REM 34333 3 3 9 9 3€ 3€ 3€ 9€ 9€ 9€ 3€ 9€ 9€ 3€ 3€ 9€ 470 REM ** PRINT CUT жж 4952 КЕМ 500 РЕІМТ "РЕІЕМ ж ANGLE ж MIN. DEV ж ЕЕ, ІМ. ЖЖЖ 33 3333 JC 33 3€ 9€ 363€ 3€ 3C ыы. 510 FOR Y=1 TO N-i 520 FOR X=1 Tü 4 S30 IF AcY¥YsX)=0 THEN GOTO 550 540 PRINT FCY): TAB &;"+*+ "АСУ, Xd; TAE 143 "ж "#D(Y Ís X); ТАЕ 243" ж "FNCYs X) 550 NEXT X S560 NEXT Y 570 PRINT "4333 3 3 3 3€ € 3€ X 39€ 3€ 3€ 3€ 3€ 3€ XXX 3333€ (X! S80 FRINT $590 PRINT »» "AVERAGE REFRACTIVE INDICES" &OQ PRINT U33333 3433383333 HEHE хын 610 PRINT "РЕТЕМ"» "REF. IND." 620 FOF X=1 TO N-i 630 PRINT FCX) ZCX) 640 NEXT X 650 PRINT &&O PRINT "33 39 9:9 3€ 3€ 3€ 3 EH € € € 3C3t 39€ 9€ 3€ € 9€ 9€ 9€ 9€ 9€ "' 670 GOTO 770 6580 REM 690 REM 33333939 9 ) 9 9 HEHEHE HEHE &9*5 КЕМ 700 REM **CORRECT ERRORS SLUEx- 710 PRINT 720 PRINT “INPUT C IF CORRECT:0 THERWISE":;"PREESZ NEWLINE" 730 INFUT A$ 740 CLS 750 RETURN 760 FEM жжЖЕМП SUBROLUTINE* Ж ЖҰ CC 770 STOP 720 REM #* END жж 384 Sample Printout: PRISM * ANGLE * MIN.DEV % RF.IN. & k k k k k k k k k k k k k k k k k Kk k k K k k K k k K k R k k Ro R K 1 * 59.8 * 40.5 * 1,58 1 * 60,1 * 40.2 Ж-1.,223 2 “ 61.2 * 45.3 е T2327 2 "2 ж 45.1 “71.562 2 * 52.5 ы. 45.4 * 1.558 k k k k k k k k k k k k k k k k k K k k k k k k k k k k k K k k k k K k AVERAGE REFRACTIVE INDICES k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k PRISM REF. IND. I 1.54 2 1.586 * coe k k k k An n Je à An An ХХХХЕХЕХХХЖХХХХХхХЖҰХҰ« ХА xn x x x Comments: Note the importance of a check subroutine in this type of multiple-entry program. It gives the user the chance to verify that the input data is correct. It might have been better to have written a program to deal with any number of prisms and any number of readings. Consider what changes this would make to the program. There are many other physics experiments which may be treated in a similar way. For example: (1) The value of the gravitational constant 2. simple pendulum, ; ; l , | | using the time period equation Т = 271 g for experiments with pendula of various lengths 1 to determine the average value of g resulting. (п) The determination of the velocity of sound, using a resonance tube to find the 1st and 2nd resonance lengths (L1 and L2 respectively) and using the equation V = 2f(L2 – L1), where f = frequency of the sound, and V the velocity. 4. “SERIES” Problem: We are asked to sum the series that gives us the value of e raised to the power x. This is: 3 n . © Ж x i е шы жататы аа таты. ... for any value of x, with an accuracy n! of 1 part in 100,000 (i.e. 10-7, .00001). 385 Research the problem: This is the EXP function on your computer, evaluated as a series. The resulting value of, e.g., е, will be approximately the value of EXP 3 if you used it on the computer. ‘This Is a convergent series, E value of ie term gets smaller. For example, if we take x = 2, > от! Тел 1 = 2, whilst — 3 - Xi = 1.333... , At a certain point, the effect of adding the value of another term is to increase the sum by less than the accuracy we require. The summing is then finished. Procedure: This requires a procedure which allows any term in the series to be calculated from the previous term. This is the basic algorithm for summing many series. At this stage we need to consider if it is a specific problem or whether we could extend it to deal with other similar series-sum problems. It is important to make this decision before the program is written as it is often very time consuming to modify a program at a later stage. The answer is yes. We can then restate the problem as: a program is required which will sum a convergent series to any desired accuracy (subject to the limitations of the computer's arithmetic), provided that any term may be expressed as a function of the previous term, with the information needed being the first term and the common ratio. The common ratio is the equation that enables us to calculate any term from the previous one. For our problem: take the exponential series: x^ ҳ?-! S=] $K Peres PT 2! (n – 1)! th n term In this series the first term is 1. h n-1 The common ratio = X Ded The п" term is oD! and the п-2 п-1 25 | (n — 1)" term is — — The ratio is —— (асли = —— (n — 2)! (п- 1)! xn-2 п- 1 We require an accuracy of one part in 100,000 (10-7). When the effect of adding another term increases the sum by less than this, the program should stop processing and output the result. Outline Procedure: 1 Input necessary information 2 Sum series term by term 3 Compare sum with previous value 4 Print out result when sums differ by less than required value Detailed Procedure: 1 Input 1.1 Common Ratio – may be easiest to have a re- placeable line in program. 386 2 Sum 3 Comparison 4 Output Results Input N) н ка ка .2 First term - easily input 3 Accuracy - easily input .4 Value of X - easily input .l Initialisation - set 1st term equal to given value which in turn is the sum of the series at this stage. 2.2 Next term — may be calculated by multiplying first term by common ratio. 2.3 Sum - may be calculated by adding this term to previous sum 3.1 Compare this sum with previous value then EITHER go to 4.1 if the difference is /ess than that required or go back to 2.2 if difference is more than that required. 4.1 Name of series 4.2 Accuracy 4.3 First term 4.4 Valueof X 4.5 Sum of series 4.6 Number of terms Variables Table Name of Series Value of first term in series Value of X Accuracy required (difference between terms, such that program terminates when difference smaller than this). Processing and Output ii N 51 5 51-5 TsT*X/(N - 1) Value of current term being processed Number of terms Value of Sum of series of N - 1 terms. Value of Sum of series to N terms. Difference between the sums of the series to the Nth and (N - 1)" terms, checked against value of D. Calculates value of next term in series from current term. The common ratio is set in line 260. This line must be changed for different series. Spectrum users could use the DEF FN instruction in initialisation, and the FN instruction to evaluate the expression in line 260. Try this when you have familiarised yourself with this function. 387 Flowchart “SERIES START NEWSUM = FIRST TERM SUM = NEWSUM INCREMENT NO. OF TERMS CALCULATE NEXT TERM VALUE NEWSUM = NEWSUM PLU TERM PRINT RESULTS 10 ЕЕМ Program listing "SERIES" 20 PRINT " ж» SERIES жж "s333" THIS PROGRAM SUMS ANY SERIES" ЗО PRINT ss"WHICH IS CONVERGEN T AND WHERE" 40 PRINT з» "АМҮ TERM MAY ЕЕ CA LCULATED ҒЕОМ"› з» "THE PREVIOUS T ERM" 50 PRINT »» "REPLACE LINE 260 ñ 5 APPROFRIATE" 60 PRINT ss "HIT A KEY TO START 65 REM ##FAUSE О FOR SPECTRUM **IN LINE 70 жж 70 PALISE 40000 80 CLS 90 PRINT “INPUT МАМЕ OF SERIES 100 INPUT A$ 110 PRINT “INPUT VALUE OF FIRST TERM" 120 INPUT A 130 PRINT “INPUT VALUE OF X" 140 INPUT X 150 PRINT “INPUT ACCURACY REQUI RED" 160 INPUT D 165 REM 170 REM **«FIRST TERM** 175 REM 180 LET T=ñ 185 REM 190 REM **NUMBER OF TERMS 195 REM 200 LET N71 205 REM 210 REM s*SLUM S:NEW SUM S1* 215 REM 220 LET S128 230 LET 5-51 235 REM 240 REM **xCALCULATE NEXT TERM*s 245 REM 250 LET N=N+i 255 REM **SPECTRUM USERS САМ жж **#USE DEF FN HERE жж 260 LET T=T*X/(N-1) 265 FEM 270 REM **CALCULATE NEW SLIM*#* 275 REM 280 LET $1=S1+T 285 КЕМ 290 REM **COMPARE S AND S1s* 295 REM 300 IF ABS (S1-S)>D THEN GOTO 2 30 310 CLS 315 REM **OUTPUT RESLILTS3* 320 PRINT "SUM OF “;А%:" SERIES 389 230 PRINT "3333993 93 99 3 3€ € 96€ 3t 3€ 3C 36 3€ 3€ аа ы 340 PRINT "TO AN ACCURACY OF "; D 350 PRINT 360 PRINT "FIRST TERM=";A; ТАР Оз "VALUE OF X="; 370 PRINT 380 PRINT "SUM "513" МО. OF TE RMS "+N 390 STOF 400 REM **END PROGRAM*+* Sample printout: SUM OF EXPONENTIAL SERIES Yes e fe de k kok k k k kf kok koko КККК ККК Fe de He КККК КК TO AN ACCURACY OF .00001 FIRST TERM=1 VALUE OF X=1 SUM 2.7182815 NO. OF TERMS 19 Comment: Typical examples of other series that could be summed using the same program are given below: S=1+x+x°+x'+..... С... Po 2 4 2n Cos x= 1-57 +7) TT (- "Quy for all x x? х? е yx2n+1 Sin х=х- 9; t 5 sass Le) Tno Dj e sis Sel-xtx-x-4...... if x«1 Now consider how you might improve upon this program. Ideally this should have been considered at the planning stage and not after coding. We should perhaps include a subroutine to correct the sum to the appropriate number of decimal places or routines to enable the user to check that input data is correct. We could LPRINT directly to the printer for our hard copy printout, to avoid using COPY. 9. “GRAPH” Problem: 'To produce a useful hard-copy graph of various functions (Y 2 function X) in the positive quadrant (X and Y positive), with titles and scales included. Research the problem: The program must allow a variety of functions to be plotted. Thus there must be an input or a line of the program to be altered, according to the function which is to be plotted. Titles are to be printed, as are scale values. Hence we need to know the area of the screen in which we are to plot, and define the plotting 390 routine so that it keeps within this area. Indications of the scales should be visible on the plot screen, to enable approximate values to be read off. This will require inputs. Scale factors must be established so that the points to be plotted are within the defined area and good use is made of the available area, so that the graph is not cramped. The capacity to calculate the values of the dependent variable Y for a chosen range of X will be needed. Alterations of the values of X, so that the derived range of Y may be altered if necessary, should be possible within the program. As in all graphing programs, some degree of inspection and choice is required. In this case the requirement for scales to be printed requires the input of suitable intervals to make the graph functional. The program will hence require the following modules: 1 Input and calculation of function to be plotted. Revision of X values and re-calculation if required. 2 Input of X, Y scale values and calculation of scale factors. Printing of graph surround, titles, scale values. 3 Plotting of function. Outline procedure: Module1: 1 Input: Function to be calculated. Values of X to define range of X required. 2 Calculation: Calculate and store in array values of Y. Find maximum and minimum values of Y. Scale factor for X axis. 3 Output: Maximum and minimum values of Y for specified range of X. 4 Repeat 1 – 3 if required. User input to decide if required. Module 2: 1 Input: Low and High X, Y values. Scale values for X and Y axis divisions. X, Y axis titles. Graph titles. 2 Calculate: Scale factor for Y. 3 Output: Print titles, scale values, major scale intervals. Module3: 1 Input: Values of Y stored in array. 2 Calculate: X, Y plot values, in accordance with scale factors. 3 Output: Plot of function in specified area of screen. Detailed Procedure The descriptive algorithm (with user notes) for obtaining the best possible plot within defined scales is as follows. The user must be presented with the information required to make decisions as to suitable values for the X and Y axis scales. 1 Define range of values of X for which values of Y are to be obtained. 1.1 Input minimum value of X (MINX). 1.2 Input maximum value of X (MX). Note: Values of X should be chosen such that the scale divisions correspond to values of X that will fit the defined purpose of the graph (range of X required). Thus the range of X would be chosen to suit the major scale divisions of the ‘graph paper’ drawn by the program. We would choose X to be plotted on a scale running from 0 to 5, to give scale divisions of: | 0 1 2 3 4 5 along the X axis, even though we were primarily interested in the plot of Y with X in the range, say, 0.5 to 3.9, adapting the X values to the constraints of the graph scales drawn on the screen. (See the sample printout for these.) Similarly, we might choose X axis scale values of 0.4 0.5 0.6 0.7 0.8 0.9 to fit within the constraints of the display, even when the prime сопсегп was the plot of Y when X runs from 0.5 to 7.9. 1.3 The scale factor for X (DX) to be used in the calculation loop to derive values of Y is then (Number of points to be plotted оп X axis/(Maximum X - Minimum X)). DX = 50 (МХ-МІМХ) for the ZX81 and 200 (МХ- MINX) for the Spectrum. 2 Calculate values of Y for each value of X. 2.1 Set X equal to minimum value of X (MINX). Start calculation loop. 2.2 FOR each plot division on X axis (1 to 50 on ZX81, 1 to 200 on Spectrum). 2.3 Calculate Y = (Function of X). Use VAL to calculate value of function input as string. 2.4 Store value in array N (N(F) = Y). 2.5 Increment X for next plot point (X = X + DX). 2.6 NEXT plot point on X axis. End of calculation loop. Note: The values of Y are now stored in array N. We now require to know the minimum and maximum values of Y that have been produced by the calculation. We must search the array N for these values. 392 3 Search Array for Maximum and Minimum values of Y. 3.1 Set Maximum value and Minimum value variables (MAXY and MINY) equal to first Array element. (MINY = N(1),MAXY = N(1)). Start search loop. 3.2 FOR each element in array (N(2) to N(End)). 3.3 If array value is less than minimum value variable (М(Е)< MINY) then set minimum Y variable equal to array element (MINY = N(F)). 3.4 If array value more than maximum value variable, set this variable equal to array element (MAXY = N(F)). .) NEXT array element. Inspect Range of Y. 1 Print maximum, minimum Y values (МАХҮ,МІМҮ). 2 Present menu choice of: (i) Recalculating for a different range of X. Program returns to 1.1 if selected. (11) Choosing Y axis values. Note: The user must now select the scale values for a range of Y such that all values of Y are within the range chosen and maximum vertical spread of plot points is achieved to avoid a cramped plot. This latter is the same decision as was made for the X axis values. A suitable scale must be chosen to conform with the scale divisions presented on the screen. The Y axis has three scale sections, requiring four scale values at the vertical divisions of the graph. If MINY were 0.12 and MAXY were 3.6 for a given range of X, for example, we might choose to set the minimum scale value for Y as 0, and the maximum as 4.5, allowing intermediate values of 1.5 and 3.0, which correspond to the scale divisions, so that the Y axis will be labelled: Qe oop C1 € Cn This gives the maximum vertical spread of plot points. Having made this decision, the user can input the maximum and minimum Y axis values. The decision can also be made to return to the start of the first module and re-define the values of X, choosing a different range (choosing to calculate for X = 1.5 to 7.5, for example, rather than the original choice of 0 to 6 for the range). This re- calculation can be done repeatedly until the best possible Y values for placing on the graph have been found, within the constraints of the ranges of X that are acceptable. Derive scale factor for Y axis. 5 5.1 Input minimum Y for scale (Y1). 5.2 Input maximum Y for scale (Y2). 393 Note: These values are the same as will be inserted as scale values in string form for printing on the display. 5.3 Scale value for Y plot is number of plot points on Y axis divided by maximum Y minus minimum Y. This is (DY = 30/(Y2 — Y1) for ZX81, 120/(Y2 — Y1) for Spectrum.) Note: Next module of program inputs scale values as strings and the strings for titles to be printed to the screen. 6 Input scale values and titles. 6.1 Input Minimum Y. 6.2 FOR each remaining Y axis scale division (2 to 4). 6.3 Input scale value to be printed. 6.4 NEXT Y axis scale division. 6.5 Print maximum and minimum X value (MINX and MX) as reminder of X axis values. 6.6 FOR each X axis scale division (1 to 6). 6.7 Input scale value to be printed. 6.8 NEXT X axis division. 6.9 Input Graph title, Function or subtitle, X axis and Y axis titles. This algorithm is coded in the program as the subroutine (lines 1000 to 1680), called after initialisation of the arrays (lines 50 — 80). On return, all necessary data has been input or calculated. The main program prints the scale divisions on the ‘graph paper’ area of the screen, using two sets of nested loops (lines 130 — 230). Note the bypass condition in line 200 to prevent unwanted horizontal lines being printed. Scales and titles are then printed to the appropriate screen locations (lines 250 — 340). The plotting routine (lines 350 to 380) takes each value from the array N, finds the difference between this value and the defined minimum Y value (Y 1), and multiplies by the scale factor to get the Y axis plot position. Plot position is adjusted by the addition of constants to the X,Y values to be plotted, to place plot points within the graph paper area. These are: X axis: 10 on ZX81, 40 on Spectrum Y axis: 13 on ZX81, 52 on Spectrum The printout is obtained using COPY. Variables Table X$(6,4) Array to store X axis scale values (Input) Y$(4,5) Array to store Y axis scale values (Input) T$(4,25) Array for X, Y axis titles, graph titles (Input) N(50) Array to store calculated Y values E Loop variable 394 L Loop variable F$ Function input as string x Value of X MINX Minimum value of X (Input) MX Maximum value of X (Input) DX Step value for X value in calculation = Value of Y calculated. Each value stored in Array N(50) MAXY Maximum value of Y MINY Minimum value of Y M$ Menu choice (Input) Y1 Minimum value of Y axis scale (Input) Y? Maximum value of Y axis scale (Input) DY Scale factor for plot of Y values Flowchart ‘‘“GRAPH’’ Initialise col Calculate Scale factor for X Calculate Y values, Store in ағға Print Titles, Scales 395 396 Restate Yes X value No Input Y Sco le Values Calculate scale factor for Y Return Spectrum modifications: The different plot screen of the Spectrum must be taken into account. This affects scale factors and the actual plot routine, and requires a larger array for the data (values of Y for the function of X). In the same area of the screen, where the ZX81 has 50 X axis plot points, the Spectrum has (4 x 50), 200. The array N must thus be initialised as N(200). The scale factors for Y and X also need to be calculated according to this changed plot resolution. Line changes needed are as follows: 80 DIM N(200) 360 FOR F=1 ТО 200 370 РГОТЕ-40, (N(F) - Y1)*DY + 52 1120 LET DX = 200/(MX - MINX) Delete lines 1135 and 1265 1156 FOR F=1 TO 200 1236 FOR F=2 TO 200 1380 LET DY = 120/(Y2 - Y1) 1390 Delete 30, Insert 120 1520 Delete 30, Insert 200 Spectrum users can also use the DEF FN and FN instructions to define the function to be plotted (in line 1050) and to evaluate the function within the calculation loop (line 1160). Revise the program to utilise these functions when they have been dealt with in Section W. Sample printout aS шаш ЖОЛ Ode c AUT ee ` + + + + + + + + & + + FUNEM * + + + 3-0 +----+--- -—+——-- + + + = + Ф e + + + + + € RX IS + +u + + + e = = += E 1:5 t---w4y"t----t----t----t----t + F + + + + i + ж + + + + < + а” + + + £ £ тя + + + + ғ e meee pee KK tem KH tor Ф e 1.80 2.8 3.8 4.0 5.5 GRAPH PLOT OF ESUaT Zor SIN x+x Program listing 10 REM "GRAPH" 20 REM *PRODUCES GRAPH OF 30 REM *FUNCTION WITH TITLES 40 REM жАМП SCALES FOR +VE *GUADRANT 397 330 DIM Х%(6,4) DIM Y$(4,5) DIM T$(4,29) DIM N(S0) REM s*GOSUB INPUTS## GOSUB 1000 CLS REM **PRINT PAPER ++ 2 FOR Е=5 TO 30 STEP 5 FOR L=0 TO 15 PRINT АТ LiF} "+" NEXT L NEXT F FOR L=0 TO 15 STEP 5 FOR F=6 TO 29 IF Ғ/5- INT (Ғ/5) THEN NEXT J PRINT АТ L»F;"-" МЕХТ Ғ МЕХТ 1 REM Ж%%ТІТІ ЕС жж FOR F=1 TO 6 FRINT АТ 16s(F*5-1); X$ (F) NEXT F FOR F=1 TO 4 PRINT АТ 20-F#3107Y$(F) NEXT F PRINT AT 1735: T$ (2) PRINT AT 1890] Реан PRINT АТ 19sS3TSC137 АТ 215 8#T$(2)(1 TO 20) 340 TAE 250 260 270 250 290 1000 1010 Е" 1020 PRINT АТ 8»0:7%(42(1 TO 5); 0:7%(42 (6 TO 10) REM **PLOT FROM ARRAY жж FOR Р=1 TO 50 PLOT F*105s(NCFE2-Y10*DY413 NEXT F GOTO 9999 PRINT "GRAPH QF FUNCTION" PRINT »» “CALCULATION ROUTIN PRINT “INPUT FUNCTION TO BE . GRAPHED: IN": "FORM Y=FUNCTION X. 1030 PRINT “FUNCTION IS INPUT AS STRING. "s "ERROR MAY RESULT IN E *VALUATION",."OF SOME FUNCTIONS, І F THIS": “HAPPENS: REPLACE STRING INPUT","AND EVALUATION WITH INSE КТЕП", "PROGRAM LINES" 1050 1060 1070 1080 1090 1100 1110 1120 1130 1155 1140 INPUT F$ CLS РКІМТ ss "LOW VALUE OF X7" INPUT MINX PRINT з» "HIGH VALUE OF X?" INPLIT MX REM 3x*SCALE FACTOR X** LET DX=50/ (MX-MINX) REM **CALCULATE жж FAST LET X=MINX 398 1150 FOR F=1 TO 50 1160 LET Y= VAL F$ 1170 LET N(F2zY 1180 LET X=X+¢1/DX) 1190 NEXT F 1200 REM **GET МАХЭМІМ Үжж 1210 LET MAXY=N(1) 1220 LET MINY=N(1) 1230 FOR Ғ-2 TO 50 1240 IF МСЕ) <МІМҮ THEN LET MINY= NCF? 1250 IF MAXY= ":MAXY: ' 0" 1370 INFUT YZ 1380 LET DY2s30/(Y2-Y1) 1385 REM ** Y AXIS SCALES жж 1390 PRINT "Y AXIS HAS 3 SCALE D IVISIONS, " “AND ЗО FLOT FOINTS." 1400 PRINT “INPUT THE 4 SCALE VA LUES FOR Үн» "АХІ5. МАХ 5 CHF:S, " 1410 PRINT “NEWLINE FOR BLANK. " 1420 PRINT "MINIMUMC12»57?" 1430 INPUT Y$(1) 1440 FOR F=Z TO 4 1450 PRINT "VALUE ";F;"?" 1860 INFUT ҮФСЕ) 1470 NEXT F 1480 CLS 1485 REM **X AXIS SCALES** 1490 PRINT “INPUT X AXIS SCALES" 1500 PRINT "LOW X IS " MINX 1510 PRINT "HIGH X IS ":MX 1520 FRINT з» "6 SCALE DIVISIONS: 50 FLOT FOINTSON X AXIS." 1530 PRINT "SCALE VALUES MAX.4 C HRS, "s "FIRST INPUT IS LOW VALUE. 1540 FOR F=1 TO é 1550 PRINT "SCALE VALUE ";F;"?" 1560 INPUT X$(F) 1570 NEXT F 1580 REM **TITLES#* 1590 CLS 399 1600 PRINT "INPUT GRAPH TITLE (М АХ 25 CHR)" 1610 INPUT T$(1) 1620 PRINT “INPUT FUNCTION OR SU ETITLEC2O","CHRS MAX)" 1630 INPUT T$¢2) 1640 PRINT “INPUT X AXIS TITLE ¢ 20 CHRS MAX)" 1650 INPUT T$(3) 1660 PRINT “INPUT Y AXIS TITLE¢2 ж5 CHRS) " 1670 INPUT T$(4) 1680 RETURN 9990 REM 3*ENLD* 9999 STOP 6. “ELEMENT” Problem: To calculate for a chemical compound: (i) Percentage elemental composition and molecular weight or (1) molecular formula from inputs of, for (i), Number of atoms each element and for (ii) Percentages of each element. These are complementary calculations. Research Problem: We require a program that performs two separate operations. The common requirements will be the Element names, symbols and molecular weights. We choose to input and store these as data in arrays on the computer. This will require an input routine that is not used every time the program is run, and could be edited out. The elements involved should be capable of being changed to facilitate different analyses, and this must be allowed for in our program. This is an advantage over the alternatives of either defining all data with LET statements or the use of DATA and READ (which are only available on the Spectrum). The program must be split into two processing sections. The first of these (percentage elemental composition and molecular weight) requires an input for the number of atoms of each element. We can use a loop for this, using the loop variable to access the stored element names. Molecular weight equals the number of atoms of each compound multiplied by the atomic weight. This can be calculated within the input loop. Molecular formulae are then derived from the atomic symbol, plus the number of atoms, for each of the elements concerned. Percentage composition for each element is the number of atoms of the element, times the atomic weight of the element, divided by the molecular weight. The second section of the program requires an input loop for the percentage of each element. The proportion of atoms of each element will then be the percentage divided by atomic weight. This can be calculated within the input loop. To calculate the molecular formula, we require to know the minimum (to give us the smallest number of 400 atoms of any of the elements) elemental proportion. We can check this through another loop. The number of atoms of each element is then the proportion of each element divided by the smallest proportion. We could round this to integers, but will do so to two decimal places because the actual molecular formula may be a multiple of the derived formula. We should also indicate this possibility to the user. Zero inputs will be required when elements do not occur in the compound concerned. For a common organic analysis the following data will be stored via the input routine: HYDROGEN H 1.008 CARBON C 12.01 NITROGEN N 14.008 OXYGEN O 16.00 PHOSPHOROUS p 30.98 SULPHUR 5 32.06 CHLORINE CL 22,427 BROMINE BR 79.916 The data entry module is keyed in and the data input as above. The lines 15 to 160 could then be deleted if required, leaving the data stored in the arrays and available for access, as long as RUN is not used (or CLEAR). Spectrum users should replace line 3000 with: 3000 SAVE “ELEMENT” LINE 3010. The program is then SAVEd to tape by using GOTO 3000, when it stops at line 1990, or run again by keying in GOTO 200 as a command. You may like to derive an additional user dialogue to ask if the user wishes to SAVE or re-run the program, and according to the response, send control to the relevant line number. The procedure for the program is given below. Detailed Procedure: 1 Data Entry Module 1.1 Dimension arrays for data: Element Names, Element Symbols, Atomic Weights FOR each input (1 to 8) Input Name, Symbol, Atomic Weight GOTO subroutine to justify atomic weight (5 below) NEXT input Print user warning about the use of RUN ка кА ы ы қа O олњ OG N 2 Menu 2.1 Print Instructions and Menu 2.2 If second calculation required, GOTO 4 2.3 If first calculation required, proceed to 3 401 3 Percentage Element Calculation 252 3.2 4.4 Input: 3.1.1 Reference for compound 3.1.2 Initialise arrays, molecular weight variable 3.1.3 ^ FOR each Element (1 to 8) 3.1.4 Input number of atoms present 3.1.5 Calculate total molecular weight (Molecular weight plus (number of atoms * atomic weight)) 3.1.6 NEXT Element Processing/Output: 3.2.1 Print Reference, Molecular Weight 3.2.2 КОК each Element (1 to 8) 3.2.3 Print Symbol, number of atoms 3.2.4 NEXT Element 3.2.5 КОК each Element (1 to 8) 3.2.6 If no atoms present, GOTO 3.2.10 3.2.7 | Calculate percentage as (Number of atoms times atomic weight) divided by molecular weight of compound, times 100 3.2.8 | GOSUPB (5) for rounding and justification of results 3.2.9 | Print Element symbol, percentage 3.2.10 NEXT Element 4 Molecular Formula Calculation Input 4.1.1 Reference for compound 4.2 Initialise Arrays FOR each Element (1 to 8) Input percentage present Calculate proportion of Element as percentage present divided by atomic weight 4.1.6 NEXT Element Processing/Output: 4.2.1 Print reference 4.2.2 Set C = 100 for percentage calculation 4.2.3 FOR each Element (1 to 8) 4.2.4 TH proportion is zero, GOTO 4.2.6 4.2.5 If proportion less than current value of C, then let C equal proportion of element 4.2.6 NEXT Element 4.2.7 | FOR each Element (1 to 8) 4.2.8 If proportion is zero, GOTO 4.2.12 4.2.9 Number of atoms equals proportion divided by smallest proportion present, C 4.2.10 | GOSUB (5) for rounding and justification to 2 d.p. 4.2.11 Print Symbol, number of atoms 6.2.12 NEAT Element 4.2.13 Print user warning that multiples of this calculated formula may be the actual formula 402 5 Subroutine to Round and Justify (Input of number of decimal places (P) and number to be Justified (N) from data defined in main program modules) 6 1) 2) 1 X$ set to contain P zeros 2 Integer value set as XN 3 Decimal value set as XD 4 Define X$ as rounded number string 5.5 X$ returned to main modules for printing Auto-run. An automatic RUN routine using GOTO 200 is used to prevent the user entering RUN accidentally after LOADing Variables Table Input and main program sections: Holds element names Holds element symbol Holds atomic weight Loop variable in main program Loop variable in input routine Menu choice Reference for compound Molecular weight Holds input of number of atoms of element Holds input or calculated percentage of element Holds calculated number of atoms of element Constant for calculating percentages Round and justify subroutine: N X$ XN XD F Holds number for operation of subroutine Holds string form of number returned by subroutine Holds integer value of N Holds decimal value of N Loop variable in subroutine 403 Flowchart “ELEMENT” START DIMENSION DATA ARRAYS INPUT DATA INPUT CHOICE <> YES NO INPUT INPUT PERCENTAGE FIND LOWEST PERCENTAGE CALCULATE FOR EACH ELEMENT NUMBER NUMBER OF OF ATOMS ATOMS PRINT PRINT REF, SYMBOL, NO MOL.WT, OF ATOMS FORMULA CALCULATE PERCENTAGE PRINT INSTRUCTIONS STOP FOR EACH ELEMENT PRINT PERCENTAGE 404 FOR EACH ELEMENT FOR EACH ELEMENT Program Listing 10 REM "ELEMENT" 15 REM 33499) )9 3 9 9 9 9 9 3) (99€ 1. DATA ENTRY. ROUTINE CAN BE DELETED WHEN ENTRY COMPLETE. 325553555554 20 DIM Е%с(8:310) 30 DIM 5%(8»20 40 DIM МСЕ) 50 PRINT ~ ELEMENT SYMBOL MOL. WT. " 55 PRINT 60 FOR X=1 TO & ез REM ** ELEMENT МАМЕ жж 70 INFUT Е%(Х) 75 REM ** ELEMENT SYMBOL жж 20 INFUT S$*$(X) 85 REM ** ATOMIC WEIGHT жж 90 INPUT MCX) 75 REM *INITIALISE FOR GOSUBs* 100 LET Рс 110 LET N=M(X) 120 GOSUB 2000 130 PRINT X: TAB S;E$(X); TAB 1 4;S$€$(X); TAB (27- LEN X$); ХФ 140 PRINT 150 NEXT X 160 REM жн INES 15 TO 160 CAN BE DELETED AFTER DATA ENTRY AND REST OF FROGRAM ENTERED MUST USE #60TO 200% TO USE PROGRAM: NOT RUN: TO PRESERVE DATA. 170 REM **END 1. жж ЭН 180 REM 200 REM 33933399 3 99 00€ EHH (90 2, FROGRAM MENU ТП CHOOSE CALCULATION CEEE ETETE EEEE EEEE EEEE EE 210 PRINT "CHOOSE CALCULATION Е EQUIRED: - " 220 FRINT 230 PRINT "TO INFUT NUMBER OF A TOMS AND GETPERCENTAGE ELEMENT С OMPOSITION AND MOLECULAR WEIGHT INPUT E" 240 PRINT 250 PRINT “TO INPUT PERCENTAGE ELEMENT ANA-LYSIS AND GET MOLECU LAR FORMULA INPUT M" 260 INFUT A$ 270 IF AS <> "E" AND AS <> "M" THEN GOTO 260 280 CLS 290 IF A$-"M" THEN GOTO 1000 405 295 КЕМ жж END 2, жж +++ Ж JE ЗЕ JOE 555552555555 хх 3€ 3€ € 3€ 3€ 9€ 3€ 9€ € € 9E € EE CE З. PERCENT ELEMENT ЗЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЗЕ AE FE ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ 55) 300 PRINT "ENTER REFERENCE FOR THE COMPOUND" 310 INFUT F$ 320 REM жж INITIALISE жж 230 DIM A(S) 240 LET MOLWT=0 200 DIM PCS) 360 FOR Е=1 TO 3 270 FRINT "NUMBER OF ATOMS OF " TESE) 7 "2" 380 INPUT ACE) 390 LET MOLWT=MOLWT+ CACE) *MCE2) 400 NEXT E 410 CLS 420 REM **CALCULATE AND PRINT#* X*RESULTS жж 430 PRINT "MOLECULAR WEIGHT AND COMF' QS IT LON ХА 9€ 9€ 3€ 3€ 3€ 96 9€ хын 440 FRINT 450 PRINT "ЕЕЕ: "ЕФ 460 PRINT 470 FEINT “MOL. WEIGHT= "s: MOLWT 480 PRINT 490 PRINT "MOL. FORMULA: "; S00 FOR E=1 TO 8 510 IF А(Е221 THEN PRINT S$(E); ACE»; 520 IF AtE?)z1 THEN РЕІМТ Z$(E»; wow NEXT Е 240 PRINT “a "os 220 FOR Есі TO 260 IF АСЕ) =0 THEN GOTO 620 565. REM *xCALCULATE FERCENTAGESZ* 370 LET РХ(Ео-А(ЕзожМСЕО /MOLWT* 100 575 REM *INITIALISE FOR FOLIND2 x3xSLEROLUTINE EE 380 LET МЕСЕ) 990 LET Pe2 £00 GOSE 2000 610 PRINT "FERCENT ";5%(Е); TAB (198- LEN ХФ) 7 X$ 620 NEXT E &22 REM **xCOPFY HERE FOR FEINTED *hFEZULTZ xk 230 GOTO 12500 406 640 REM жж END 3. жж 355555555524 55553554 é50 REM 290 REM 3JX9 393339 Ж 33 3333333333 4, MOLECULAR FORMULA HHH HAH HH HHH HHH HHH HEHE 1000 PRINT “ENTER REFERENCE FOR COMPOUND" 1010 INFUT F$ 1020 REM **IIM ARRAYS+*+* 1030 DIM ЕСЕ) 1040 DIM NCE) 1050 РЕІМТ 1060 REM жжІМРІТ FERCENTAGES** 1070 FOR E=1 ТО 8 1080 PRINT "РЕРСЕМТ OF ";E$¿(E);" 1090 INPLT PCE) 1095 REM **CALCULATE FROPORTION® 1100 LET N(E)=P(E)/M(E) 1110 NEXT Е 1120 CLS 1120 REM **#CALCULATE AND PRINT** RESULTS жж 1140 FEINT “*MOLECULAR FORMULA*" : ТАР OF "ххх € 39€ 3€ 9€ 3€ 9€ HE" 1150 FRINT 1160 PRINT "REF:";:R$ 1170 PRINT 1175 REM **CALCULATE MINIMUM 3s XxPROPORTION ELEMENT жж 1180 LET C-100 1190 FOR E-1 TO 8 1200 IF МСЕ) =0 THEN GOTO 1220 1210 IF N(E) “INFUT YOUR CHOICE" 310 INFUT M 320 IF М<1 ОЕ М>7 THEN GOTO 300 325 IF Mzé THEN GOTO 6000 330 CLS 340 GOSUB M*1000 418 350 CLS 355 IF X=1 THEN GOTO 20 360 GOTO 210 290 REM KEKE t9 € € 9€ 9€ € € 9E 9€ € EE жж CREATE FILE SUE жж +++ 3C + 3E 9E 3E 3€ EXEC EE EXE E XE JE EXE XE 1000 LET F=TF+1 1010 IF F <= 10 THEN GOTO 1020 1015 PRINT "««NO SPACE FOR АМОТН ER ҒЕПЕжж"») "ОМ RETURN TO MENU CHOOSE SAVE", "OPTION TO KEEF CUR RENT FILES"."THEN ERASE FILES AN D START NEW": "FILE ARRAY. " 1016 FAUSE 300 1017 RETURN 1020 PRINT "READY TO CREATE FILE NO. "FF 1030 PRINT АТ 2:0;7"INFUT CASSETT E REF. (4 CHRS MAX)" 1040 INFUT СФСР) 1050 PRINT АТ 2:0;E$; АТ 230: B$: "?(15 CHRS MAX)" 1060 INPUT МФ СР) 1070 PRINT АТ 230:Е%: АТ Z230:"IN PUT FROG. NAMES AND TAPE COUNTS" 1080 PAUSE 300 1090 FOR М=1 TO 10 1100 PRINT АТ 4:0; "PROGRAM "FN 1110 PRINT 6$;" ? (15 CHRS MAX)" 1120 INPUT РФС(Ғ»МО 1130 PRINT АТ 5з0:Е%; АТ 5% О0:Н%; " FROM ?" 1140 INFUT TCFsNs1) 1150 PRINT АТ 5,11;"ТО ? ы 1160 INFUT TCF »Ns2) 1170 PRINT АТ 530:Е%: AT 5» 0; "АМ OTHER FROGRAM ?(Ү/М2" 1180 INFUT M$ 1190 IF M$="N" THEN GOTO 1220 1200 IF M$ <> "М" AND M$ <> "Y" THEN GOTO 1170 1210 NEXT N 1220 CLS 1225 LET TF=TF+1 1230 PRINT "CREATE ANOTHER FILE (F) VIEW" s “CREATED FILE (V) OR M ЕМ) (M)?" |+" INPUT F»V OR W " 1240 INPUT M$ 1250 IF M$ <> "F" THEN GOTO 1290 1260 LET F=F+i 1270 CLS 1280 GOSUB 1020 1290 CLS 1225 IF M$-"V" THEN GOSUB 2020 1300 RETURN 1980 REM «эке кен 1990 КЕМ жж VIEW FILE SUB ** + 1991 REM HHH 0909090 (3 9 9 EERE 2000 PRINT "WHICH FILE NUMBER?" 2010 INPUT F 419 2015 REM **ENTRY FROM OTHER SUBS 2020 CLS 2030 IF TF <> 0 AND F <= TF AND F >= 1 THEN GOTO 2110 2040 PRINT "NO FILE WITH THAT NL! 2050 PRINT "MENU (M) ОЕ VIEW OTH ЕК FILE 7" 2060 INFUT M$ 2070 IF M$="V" THEN GOTO 2000 2080 IF M$-"M" THEN RETURN 2090 PRINT "FOLLOW INSTRUCTIONS PLEASE. " 2100 GOTO 2050 2110 CLS 2120 PRINT FSF 2130 PRINT A$ CSIF? 2140 PRINT "Жж 3€ 3€ 3€ 9€ 9€ 9€ E 9€ 3€ 9€ JC 3C3€ 3€ 3€ 3€ 3€ 3E 9€ 9E 3E '" 2150 FRINT G$; ТАЕ 20;H$? TAB 20 ; 1% 2160 PRINT "-------------------- 2170 ҒОЕ N=1 TÜ 10 2180 PRINT Nr", "ЭРФС(ҒЭ М9? TAB 20 ТЕМ 12; TAB 26: TCF» NS Z2 2185 NEXT М 2190 PRINT АТ 21:0: "ҒЕІМТСР 2» МЕХ T ЕПЕСҒ; OR MENLICM) " 2200 INFUT M$ 2210 PRINT AT Z1:0;E$ 2220 IF M$z"P" THEN COPY 2230 IF MS «> "Е" THEN GOTO 2510 2240 LET Е=Е+1 2250 IF F <= TF THEN GOTO 2200 2290 DLS 2260 PRINT "**NO FILE OF HIGHER NUMEEF3 * " 2270 FALSE 150 2280 CLS 2290 GOTO 2210 2200 GOSUE zozo 2310 RETURN КЕМ 9333 33t3(t3€ 9€ 3€ EHH REM **xREVISE FILE SUB** 795) REM ххх HHH HHH 3 OO PRINT "WHICH FILE TQ REVISE 1 Tu АҒ 3010 INFLIT F 2020 IF F <= TF THEN GOTO 3060 3050 PRINT “NO SUCH FILE" 3040 FALZE 120 3080 RETURN fat А к F3 3060 CLS 3070 PRINT "FILE "Рӯ" DETAILS W ILL BE PRINTED. "ss" PRESS NEWLIN E IF CORRECT" » “INPUT NEW DETAILS IF REQUIRED. " 420 3080 PAUSE 150 3090 SCROLL 3100 PRINT AS; СФСР) 3110 INPUT M$ 3120 IF МФ-"" THEN GOTO 3170 3130 LET C$CF)-zM$ 3140 CLS 3150 SCROLL 3160 PRINT "NEM ":a$:C$(F?) 3170 SCROLL 3180 FRINT BS;" "МСР 3190 INFUT M$ 3200 IF M$-"" THEN GOTO 3265 3210 LET N$(F)=M$ 3220 CLS 3230 SCROLL 3240 PRINT A$ CCF? 3250 SCROLL 3260 FRINT "NEW CASS. NAME "МСЕ ) 3265 SCROLL 3270 FOR N=1 TO 10 3350 FRINT "FROG. "FN?" NAME ":P$ (Fs ND 3370 INPUT M$ 3400 IF M$ <> "" THEN LET ҒФСЕ» М )zM$ 3410 PRINT AT 21:0; "PROG. "№" N AME ";PSCFsN) 3420 SCROLL 3430 PRINT AT 21,0; "ТАРЕ FROM: "; Т(Ғ» М» 12 3440 INFLIT M$ 3450 IF M$ <> "" THEN LET ТСР» № 1)= VAL M$ 3460 PRINT АТ 21%0: "ТАРЕ FROM: "; TCFsNo i337" TO: "ТЕУ N6 22 3470 INFLIT M$ 3480 IF M$ <> "" THEN LET ТСЕ» М, 2)= VAL M$ 3490 PRINT АТ 21,0; "TAFE FROM: "; T(FsN3512;" TO: "ТСЕ М2) 3495 SCROLL 3500 NEXT N 3510 RETURN 2990 REM 3J333 93333) 9 X 3X ы € 4000 REM x*xxDELETE FILE SUB** 4001 REM «ххх Хы CE 4010 PRINT “WHICH FILE DO You WI SH TO".,."DELETE ? (1 TO 10)" 4020 INPUT F 4030 IF F <= TF AND F >= 1 THEN GOTO 4070 4040 PRINT "x«NO FILE OF THAT NL! MBER»* " 4050 FAUSE 150 4060 GOTO 4430 4070 FRINT F$;Fs АФ: C$ CF) 4080 PRINT B$:" ":N$(F) 4090 FRINT АТ 10:0;"INPFUT D TQ C ONFIRM DELETION"::3»"OR M FOR MEN LI, и 421 4100 INPUT M$ 4110 IF M$ <> "D" THEN GOTO 4430 4120 PRINT АТ 1430;"ALL FILES WI TH NUMBERS >"3Fs"WILL HAVE THEIR FILE NUMBERS", "REDUCED BY ONE, " 4125 IF F=TF THEN GOTO 4220 4130 FOR N-F TO TF-1 4140 LET N$(N)=N$(N+1) 4150 LET ССМ) C$ (N12 4160 FOR L-1 TO 10 4170 LET PS(NsLI=P$(N+15L) 4180 LET T(NsL+1)=T(N+1s+sL+1) 4190 LET T(NsL+2)=T(N+1+L $22 4200 NEXT L 4210 NEXT N 4220 LET C$(CTFO-E$ 4230 LET N$(TFO-E$ 4240 FOR N=1 TO 10 4250 LET P$¿(TF+N)=E$ 4260 LET T(TF+N+1)=0O 4270 LET ТТР» №2) =0 4280 NEXT N 4290 LET TF=TF-1 4300 CLS 4310 PRINT "FILE DELETED" 4320 PRINT »% "МЕМ FILE LISTING: " 4330 PRINT 4340 FOR N=1 TO TF 390 PRINT РФ №" “FASS ССМ) 4360 NEXT N 4370 FRINT AT 21:0; "COPY NEW LIS T (G), OR MENU СМ)" 4380 INPUT M$ 4390 IF M$ <> "C" THEN GOTO 4430 4400 PRINT AT 2130;:E$ 4410 COPY 4420 CLS 4430 RETURN 4990 REM 333999 9 9 0 9 9 309€ 9€ ыы 2000 REM 3x* PRINT LABEL SUEs3«* 5010 REM 93sÓ3dmdUK3t3(93€((€ Y HEHE 5020 PRINT "WHICH FILE DO YOU WA NT ТО РКІМТ"»% "А5 А CASSETTE LA BEL? 1 TU 19 3” 5030 INF'LIT F 5040 IF F >= 1 AND F <= TF THEN GOTO 5090 5050 PRINT "#*NO FILE OF THAT МІ) MBER жж" 5060 PAUSE 150 5070 CLS 5080 GOTO 5220 5090 PRINT ›› "ЕЦЕ "ФЕ" WILL NO W BE PRINTED. “%%% "СНЕСЕ PRINTER: HIT А KEY TQ START" 5100 IF INKEY$ ="" THEN GOTO 510 © 2120 LFRINT X$; "i"; A$:C$(F); TAB 20rF$r:F; TAB Sir" F 5130 LPRINT 2%: "| “2 БФ)! "3 МСР); TAE 212 422 5140 LPRINT 2%:Х%: "8 "0%; TAE ZO 2% "УНФ: ТАЕ зір 5150 LFRINT "I": TAB 20941") I$; TAB 31" B" 5160 LPFINT X$ 170 FOR М-1 TÜ é 2180 LFRINT "Ё": №" ЗРФХРЭМО T AB 21:Т(ҒэМ1»: TAE ZS58:TCF»N$Z27 TAB 31: "8"; Z$ 510 NEXT N a400 LFRINT Y$; ХФ 5210 LPRINT wee ТАЕ 20 ;F$:F; ТАЕ 31;"I" 5220 LPRINT ҮЗІГІ "*5N$CF2; TAE 1? " [" 3230 ІРЕІМТ Y$; X$ 740 FOR N=7 TO 10 5250 ІРЕІМТ "[";N:" "PCF No? Т АЕ 21: ТСҒ»Мз1»)) TAB 25% TCFs М2); _ AE 313" I":Z 5260 NEXT N 3270 LFRINT Y$ 52280 RETURN 5990 REM 33339 )9 99 9 9 4! 9 9 3 3 HEHEHE 6000 REM ** SAVE FILES PROC жж 6001 REM 3333 9999) HEHEHE ене 6005 CLS 6010 PRINT "SAVE FILES ON ТАРЕ Е OUTINE" Т PRINT ss "CURRENT PROGRAM МА ME Is" 6030 FRI NT , 5 и пи и , 2$; "Ç "un "“ 6040 PRINT эз"ІМРІТ А NEW NAME F OR THIS “s"“FROGRAM FILE OR PRESS NEWLINE":"ONLY TO SAVE WITH CUR RENT NAME. " 6050 PRINT ss "INPUT M FOR MENU" 6060 INFUT M$ 6070 IF M$="M" THEN RETURN 6080 IF M$=""" THEN GOTO 9900 6090 LET 5%-М% 6100 GOTO 9900 6990 REM J3JQdUqcd(eogdndde 9) 99 9 9) 7000 REM **DELETE ALL FILES SUE LE EEEE EEEE EEEE EEEE EEE EE] 7010 PRINT "INPUT D TO CONFIRM A LL FILES" ARE TO BE. DELETED. ^ 7020 PRINT ss “INPUT M TO RETURN ТО MENU. " 7030 INPUT M$ 7040 IF M$ <> "D" THEN GOTO 7080 7050 CLEAR 7060 PRINT ss “INPUT NEW NAME FOR THIS. FILE" 7070 INFUT 5% 7080 LET X=1 7090 RETURN 2890 REM 3 39 * X X X34 Ж Ж 9900 REM жж AUTO-RLIN ROUTINE + 2901 REM 3J3sd3J33393 33 ЭЕ ЭРЭР 9€ ЗРЗЕ ыж 423 Sample Printout: 9910 CLS 9920 PRINT “PROGRAM NAME IS " 29°30 РЕ T NT и ии и - = $ 5 и ии "< 9940 PRINT "#*NOTE IT DOWN3*" 9950 PRINT :»"SET CASSETTE TO FE CORD АМО THEN" "PRESS A KEY TO SAVE. " 9960 IF ІМКЕҮФ ="" THEN GOTO 9926 9970 SAVE 5% 9280 CLS 9990 GOTO 200 FILE NO.1 CASSETTE REF: ЯРР1 £ £ £ X x % X % X X X X £ £ X X £ X S 33 S a $ $ $ + PROGRAM NAME TAPE СОЫМТ FROM то 1.GRAPHPLOT s 29 2.RESIST з= exu 3.STRINGSORT ес аза 4. e a S. а ж б. & г. Ta ғ Pu в. e гы ә. e гы 29. e e CASSETTE REF:RHPP1 FILE NO.i t CASSETTE NAME BRPPLICRHTIUONSÓ1 PROGRAM NAME TREE COUMT FROM то GRAPHPLOT RESIST STRINGSORT CASSETTE REF:APP1 FILE MO. | CASSETTE NAME RPPLICRHTIGOPFSsi 424 Comments: This is a fairly long program. Work through the listing, checking you understand the operation of the algorithm within each program module. The individual manipulations of arrays and lists have all been encountered before, and each program module performs a different operation on the arrays and lists holding the data. The program is not by any means ‘idiot-proof’, although it is reasonably ‘user-friendly’ and you should note the various input checks used. The program can be crashed by inputs of bad (non-numeric) data into the numeric array holding the tape counter listings, and the main menu. Any file number request is checked. The input (string or numeric) from menus is checked, in different ways. Either another input is requested, or a default return to the main menu operates. Data correction is dealt with by the View File and Revise File modules. The program could be improved in two obvious ways. The first improvement would be a search routine to find and display the cassette file containing a desired program. A new module, 8 in the main menu and line 8000 onwards in the program listing, could be added to perform this operation. The second is that you cannot both print a file (in the View/Print File module) and then step through for the next file, since after printing the program automatically returns to the menu. Consider how you would modify the flow of control in lines 2190 to 2310 to allow this. Notice as a final point that data manipulation programs are long, not necessarily because of the processing manipulations themselves, but due to necessary input checks and user dialogue. The program can be easily revised for use with your audio cassette library, or other filing purposes. The program examples included in this Unit have been selected to illuminate the various structured programming techniques discussed in the rest of the book. In order to demonstrate the maximum number of these techniques being used in practice, it proved necessary to give the programs a strong scientific applications bias. Home users will doubtlessly be dismayed to discover that there is little in this part of the book which will be of practical use to them. However, it is important that they understand the principles behind the programs in this Unit, even if they do not actually key them in. As far as games and home applications programs are concerned, the Program Library at the end of the book (Appendix VI) should provide readers with enough examples to enable them to write their own programs tailor-made to their particular interests. V4: Games Programming Games are applications programs which are not of a type which fulfils a 425 specific purpose in a functional context; that is to say they are not written to do a specific scientific, educational or data-manipulation task. This does not mean that, as programming tasks, they are frivolous. The enjoyment of playing the game on or with the computer is the application for which the program is written, but the task of programming a game is often difficult. Games programming is good practice for finding, deriving and coding algorithms and producing efficient and user-friendly programs. Graphics manipulation plays a larger part in games programming than in most applications programs, and such programs are also more interactive, requiring repeated inputs and outputs. BASIC, an interpreted language, is often slow for games purposes. Fast action graphics games (SPACE INVADERS and their spawn), are written in machine code for speed of operation, as are tactical games where exhaustive exploration of possible moves is required (such as chess). Effective games can be programmed in BASIC, however, if the amount of calculation is not too great. An area of interaction between Games and Application programming is the question of simulation. A program, given data and rules for manipulating the data, simulates a situation. In a serious application, this would be a real situation, with the manipulations performed as known or hypothesised relations from scientific knowledge. A game simulation would use invented relationships, or perhaps simplified formulae, if it dealt with a ‘real’ situation. The techniques would be essentially the same, and are used in a program in the same fashion. From the point of view of this book, games may be considered as programming exercises. All the techniques you have learnt can be put to use in writing games programs. V5: Example Programs The first program we will examine 15 a classic computer simulation, or rather implementation, of Life. This is not really a game, but a process that the user sets into operation, and observes. Invented by John Conway, the game simulates a colony of cells, which grows from the initial colony according to three simple rules. Cells are placed on a grid, and in each generation the succeeding generation is determined by the number of neighbouring grid squares which contain a cell. The rules are these: 1 Ifa cell possesses, іп the 8 adjacent grid squares, either two or three neighbour cells, it survives into the next generation. 2 А сей dies (is removed from the grid for the next generation) if it has (1) 4 or more neighbouring cells (overpopulation) or (11) 0 or 1 neighbours (isolation). 3 Each grid square which is empty, but has exactly three neighbours is a birth cell, and a cell will appear in this position in the next generation. 426 To implement this on the computer, manipulation will be involved since a grid is a 2-D array. It is also necessary to have more than one such array, since the grid of Generation (n + 1) is defined from the grid of Generation (n), and none of the cells of Generation (n) can be altered until the checking process is complete. The array of Generation (n) must have each grid position checked, and the number of neighbours counted. In accordance with the rules, the future of the cell at that position is determined and, if empty, whether a cell will be born. This data is stored in one array, and then the other array is updated to take account of the changes. Spectrum users should delete lines 220 and 390. Program Listing S REM "LIFE" 10 PRINT TAB i1z:"*LIFE«" 20 FRINT 20 DIM 85(16%162 40 DIM Bcté.1ié) 50 DIM Ас, 2) 80 LET GEN=0 70 REM #ENTES START COLONY+* SO PRINT "ENTER START COLONY"; "ON A Xé GRID"ssse"INFUT 6 STRI NGS OF SPACES AND "."AZTERISKZ ¢ жу" 70 PRINT 100 FOR F=1 TO ё 110 PRINT "STRING ";F; 120 INFUT A$CF) 130 PRINT " “SASCF) 140 NEXT F 145 REM xFLACE COLONY IN ARRAY* 150 FOR F=1 TO é 140 FOR Z=1 TO ë 170 IF A$(FyZ)="*" THEN LET ЕСЕ +9, 1+5) =1 120 МЕХТ 2 170 NEXT F 200 GOSUB 1000 205 REM *INCREMENT GENERATIONS 210 LET GEN=GEN+1 220 FAST 230 FOR Х=2 TÜ 15 240 FOR Үс2 TO 15 250 REM *SET COUNTER* 260 LET C=0 265 REM *CHECK NEIGHBOUR CELLS 270 IF А(Х-1:Ү) =1 THEN LET C=C+ 1 280 IF ACX-isY-1)=1 THEN LET C= С+1 290 IF АсХ-15Ү+1)=1 THEN LET C= C+1 300 IF A(X:Y+1)=1 THEN LET C=C+ 1 310 IF ACXsY-13=1 THEN LET C=C+ 1 427 it is obvious that array 320 IF ACX4+1;Y-1)=1 THEN LET C= +1 330 IF ACcX41»Y2021 THEN LET C=C+ 1 340 IF ñ(X+1yY+1)=1 THEN LET C= [^41 34& REM xDECIDE IF BIRTHx 350 IF ACX:Y220 AND Cz3 THEN LE T BCX*Y2z1 255 REM *#DECIDE IF DEATH* 360 IF А(553Ү9гті AND (Crt OR С<2 ) THEN LET ECX:Y)=0 370 NEXT Y 3S0 NEXT X 390 SLOW 400 GOTO 200 1000 CLS 1002 PRINT АТ 931: "GENERATION "; GEN 1010 FOR X=1 TO 16 1020 FOR Y=1 TO 16 1025 REM ЖИРПАТЕ ARRAY Аж 1030 LET ACX» YOzBCX YO 1035 REM *PFINT ARRAY* 1040 IF ACX:Y)=1 THEN PRINT AT X +Z 153 OH” 1050 IF А(ХзҮз-0 THEN FRINT AT X T2iY46:" " 1060 NEXT Y 1070 NEXT X 1080 COPY 1090 RETIREN 428 Flowchart of “LIFE? START INITIALISE ARRAYS, GENERATION PRINT INSTRUCTIONS PRINT STRING NUMBER PLACE IN ARRAY B 429 INCREMENT GENERATION COUNTER C = No. of NEIGHBOURS FOR A(X,Y) A(X,Y) (OCCUPIED NO =1 B(X,Y) =1 (BIRTH) 430 Flowchart of ‘ІЕЕ’ - Subroutine 1000 ENTRY PRINT GENERATION COPY SCREEN RETURN 431 PROGRAM STRUCTURE The program breaks down into the following sections. (1) Initialisation (lines 30 — 60). Two 2-D arrays, 16 x 16 are set up, with a 6 string array to hold the start colony. The generation counter is set as 0. (üu) Input of start colony (lines 70 — 140). 6 strings of 6 characters are entered and printed out. (iui) Start colony is placed in array. The lines 150 — 190 place 1 (representing a cell) in array B when an asterisk is present in the string array entered in (11), in the central 6 x 6 block. (iv) Print Subroutine. Line 200 sends control to the subroutine. This uses a double loop to set array A as array B, then prints asterisks on the grid for each 1 found in array A. Note that at the end of this subroutine arrays À and B hold the same data. The screen is copied, and control returned to line 210. (v) Checking of population to determine next generation. The generation is incremented and the computer put into FAST mode. The double loop is set up, and each cell in array A is checked in turn for the number of neighbours it possesses. The counter C is incremented by 1 for each neighbour. Line 350 places a ‘born’ cell into array B if the cell in array A is blank, and the number of neighbours is three. Line 360 kills any cell with more than 3 or less than two neighbours. The corresponding array B element is set to 0. At this point array B holds the revised population for the next generation. Array À must be left alone during the check procedure. This is the reason why the two arrays are made equivalent in (iv) above. (vi) Control is returned to line 200, and steps (iv) and (v) repeated. The pattern of asterisks input initially determines how the population develops. Some patterns die out, after a number of generations, some enter a stable sequence that repeats, and there is a general tendency towards symmetry if a population survives long enough. The next game is also an implementation of a favourite game for computers, which has existed since the days of printout-only terminals (which is where the instruction PRINT in BASIC comes from, as a hangover from hard-copy terminals transferred to implementation on a screen). The basic idea, upon which many variations have been created, is that a landing must be made on the lunar surface at a speed low enough to prevent a crash. Rockets can be fired to slow the craft, but the fuel supply is finite. If the fuel supply is exhausted, a crash is inevitable. The game was originally played with a printout of the data 432 only. This version uses one side of the screen for a graphic display, and prints the data on the other. Spectrum users must replace line 40 with 40 PAUSE 0. 2 REM "LANDER" 10 PRINT TAE 10; *LANDER*";: AT 4,0; "LUNAR LANDING GAME. YOU ARE "S"INITIALLY 500 METRES ABOVE T HE", "SURFACE OF THE MOON. YOLI НАМ E “5 "100 "FUEL UNTTS " ZO PRINT "FRESS Е TO FIRE ROCK ETS TO SLOW DESCENT. EVERY FIRING USES 5 FUEL UNITS. YOU MUST LAND SLOWER THAN z TO SURVIVE. GOOD L. ШЕ, " 30 РЕІМТ з» "FRESS A KEY TO STA КІ” 40 FALSE 40000 45 REM ** I NITIALISEx* SO CLS &O PRINT АТ 20315) "deka ulis " 70 LET Fz100 mO LET Н==00 90 LET 5-15 72 REM **xzTAOàRT OF ІППРжж 100 LET V=0 110 IF Hz&OO THEN РЕІМТ АТ 20-Н /30320;" " 120 PRINT AT 105 “FUEL: “РЕТ "а" : TAB O:"HEIGHT:":H;" "? TAB O;" SPEED; "3355" " 135 REM *#*#CHECK ROCKETS жж 140 IF INKEY$ ="F" AND F >= 5 T HEN LET V=Š 150 IF V THEN PRINT AT Zi-H/30: 203" Vy" 160 IF F<5 THEN PRINT АТ 1з7: "% EMPTY +" 170 LET FeF=y 180 LET S=S+2-V 190 PRINT АТ 20-H/30; 20; " ii TAB 20; " 4 192 КЕМ жж СНЕСЕ IF LANDED жж 200 IF H<30 THEN SOTO 230 210 LET HzH-Z 220 GOTO 100 225 REM ** LANDING RESULT жж 230 IF 5<4 THEN PRINT АТ 21,10; "PERFECT LANDING" 240 IF 545 AND 524 THEN PRINT А Т 21310: "BUMPY BUT SAFE" 220 IF © >- & THEN PRINT АТ 21, 10: "CRASHED AND SMASHED" 260 PRINT АТ 1230: "ANOTHER GAME ?СІМРИТ Y OR ND" 270 INFUT AS 433 ЕО IF A$z"Y" THEN GOTO 20 то REM *END* 2 2 4-- в. Lines 10 to 30 print instructions, and line 40 stops the program until а key is pressed. Lines 50 to 90 clear the screen, print the “lunar surface' and set the variables: F is fuel units, H is height above surface, S is speed of descent. The main program is in the loop between lines 100 and 220. V is set to zero as a flag, and the craft is printed by line 110 if the scale set allows it to be on screen. The craft disappears off the top of the screen if the height is greater than 600 since the PRINT AT instruction scales so that 1 print line = 30 metres of height. Line 120 prints the current data. Note the spaces after the variables to overprint if the values decrease, or in the case of the speed becoming positive after being negative. (Negative descent speed means ascent.) Line 140 checks if the R (for rockets) key is being pressed. If it is, V Is set to 5. Line 150 prints rocket exhausts below the craft if the R key was pressed (evaluated by V = 0 = False if not pressed, V = 5 = True if pressed). The fuel is checked (line 160) and reduced by the value of V if not empty. The speed is adjusted by increasing it, then reducing it by the value of V if the rockets have been fired. Line 190 overprints the craft and rockets, and 200 checks if the surface is near enough for landing to be assumed. If it is, control is transferred to the landing message section. If not, the height is adjusted and the program loops back to repeat the process. Notice that the variable V is used in three ways within the loop, and that the loop structure, using INKEYS to see if the player has input instructions, is common in interactive games. It provides a simulation of a real-time process. In this game, the speed is assumed to be metres per second (hence the simple LET H = H - S of line 210). It is actually nominal ‘metres’ per program loop! Other games can wait for inputs, but the use of a loop allows the inexorable attraction of gravity to go on its way unless the player does something. Spectrum users, with their faster computing, may wish to insert a PAUSE instruction in the loop. Programming for this type of game can show the programmer that certain structures of programs are inefficient in program execution, since conditional branches to routines requiring calculation will noticeably slow the loop. In the interests of a good game, structured programming practice may be set aside and speed of execution can become a goal in itself. However, remember not to transfer these techniques to serious programs! Games programming can become extremely complex when we consider the strategy and tactics which must be built into the response from the computer. We have dealt with only the simplest form of game, and have not included any of this type of game. We suggest that you 434 put to work the techniques we have shown you in this text to analyse some of the tactical games in the popular computing magazines, if this area Interests you. In order to start learning to appreciate the problems involved, you could start by writing a program to play Noughts and Crosses. You may think this is a very simple game, but it is a surprisingly difficult one to program! 435 E o f СОЖ быш — 2 s PART FIVE COVERING THE WHOLE SPECTRUM чон YET wig) 4° SYM SECTION W: THE SPECTRUM W1: The Spectrum System and Keyboard This Unit introduces the Spectrum microcomputer system. As a Spectrum user you have been referred to this Unit because, whilst the BASIC language that both the Spectrum and ZX81 use (Sinclair single keystroke BASIC) has only minor differences between the two machines (although the Spectrum has additional features that the ZX81 does not possess, such as colour, high-resolution graphics and sound), there are greater differences in the arrangements of the keyboard. The Spectrum system is also simpler to set up and connect. After reading this Unit, you should return to the start of Section C (page 19) to start using the BASIC language, once the keyboard and the way to access all the confusing array of characters grouped on and around each key have been explained. Sections A and B are for the ZX81 only, but you will find in this Unit the same information as it applies to the Spectrum. The main text takes you through the Sinclair BASIC language, using the same instructions for the ZX81 and Spectrum, any minor differences being noted. This involves the introduction of a few of the Spectrum’s enhanced BASIC instructions, but most of the additional facilities of the Spectrum are covered in the next Units, to be read after you have worked through the main text and have learnt the BASIC programming techniques. SPECTRUM SYSTEM DESCRIPTION We assume that you have in front of you the components of your Spectrum system. This consists of: 1 The ZX Spectrum microcomputer. 2 Either 16k of internal RAM or 48k (although nothing in this book demands more memory than 16k). 3 The ZX power supply, with the correct plug attached for the a.c. power sockets you have. 4 The ZX printer and its socket. 5 A domestic TV to act as a display monitor. 6 A mono cassette recorder, with an a.c. supply lead (if not battery powered). 7 The aerial/antenna cable which connects the Spectrum to your TV set. (In the U.S. this is via a switch box.) 8 A pair of cassette recorder leads, fitted with 3.5mm jack-plugs at either end. These components make up a complete system, the least crucial part of which is the ZX printer. If you do not have a printer then you can ignore the printer-related sections of this book and learn BASIC 439 programming techniques just as well. It is extremely useful, however, to have a printer both for hard-copy printouts of results and, more importantly, for program listings for documentation purposes. The cassette recorder should preferably be mono, since stereo tape deck recording heads can cause problems, even used on only one channel. The cheaper recorders work somewhat better (due to the less sophisticated audio circuits being better for handling the crude form of the computer’s signals) than more expensive ones, but get one with a tape counter, as finding programs without one can be an irritatingly time-consuming process. FIGURE 3 SPECTRUM SYSTEM DIAGRAM a.c. household power supply TV AERIAL CONNECTION POWER SUPPLY TELEVISION 9V d.c. кезі PRINTER CASSETTE // RECORDER Ж U.S. Users тау have antennae on/off switch fitted in aerial lead, shown as dotted box in diagram. 440 FUNCTION OF COMPONENTS Here is a brief rundown of the function of each of the components of the Spectrum microcomputer system. Device Spectrum computer board Keyboard TV Set Cassette recorder Printer Power Supply Cables Function Data processing and control of inform- ation handling. Input from keyboard or cassette. Output to ТУ screen and printer. Also holds the 16k or 48k of RAM memory. K stands for kilobyte. One byte is eight bits, which are the binary digits (0 and 1, represented by on-off switches in the computer) computers work with. A kilobyte is roughly 1000 bytes, hence the name. (It is actually 2^, 1024). Input of information. Programs, data and commands are keyed in. On-line control. Used as V.D.U. (visual display unit) monitor. Provides on-line output of information - visual display of programs, results (data, graphs, pictures) and control commands. Off-line storage of information Program data are stored (written) as coded electromagnetic impulses on cassette tapes. They can be played back (loaded) at any time for use again. The computer reads the data from the tape. The Spectrum will also be able to use the microdrive, storing the coded impulses on a magnetic-coated disc, when it becomes available. Output device, to provide a permanent printed record of the screen display, program listings or information in the computer memory. Prints on electro- sensitive paper. Supplies the d.c. current (9 volts at 1.2 amps) to run the computer, RAM pack and printer, from the household power supply. To interconnect the devices which make up the system. The printed circuit board inside the Spectrum holds and connects the 441 IC (integrated circuit) microchips which provide the computing facilities. These are: 1 4 Z80A CPU (Central Processing Unit) microprocessor chip which is the heart of the system. It is used in many other microcomputers, and performs the arithmetic manipulations. ROM (Read Only Memory) chip holds the 16k BASIC interpreter which translates BASIC instructions into the machine-code instructions that the 780А operates with. The data in this chip is fixed, hence the name, and also stable - it remains when the power is switched off. RAM (Random Access Memory) chips provide the memory store. This is either 16k or 48k, depending on which version of the Spectrum is owned. This memory is volatile — the data is stored as electrical impulses and is lost when the power is switched off. This memory stores the BASIC program, the values of variables (including some system variables that the computer uses for to organise its own affairs), a memory picture of the ТУ screen display, and the stacks which hold the numbers whilst they are being manipulated. The memory organisation is described in Section U. The Logic Chip co-ordinates the operation of the other chips. Also mounted on the board are the stabiliser for the 5 volt supply the computer takes from the power-supply socket, the colour TV signal encoder and modulator circuits and the sockets for the connecting cables to the ТУ and cassette recorder. There is also a small speaker for the sound output. CONNECTING UP 1 2 Set aside an area to work in and set up your television, Spectrum, cassette recorder, printer (if you have one) and the Spectrum’s power supply, as shown in the diagram of the system (Fig. 3). Always remember to connect the printer to the back of the Spectrum before you switch the power on for the ZX power supply. With the printer connected, the TV aerial lead connected to the ТУ socket on the Spectrum, and the ‘EAR’ and ‘MIC’ leads correctly set up as below, you can then plug into and switch on the a.c. power (household) supply. Connect the printer into the socket at the rear of the Spectrum. Make sure the gap in the board at the rear of the Spectrum connects with the plastic piece in the printer socket, then push firmly home. Connect one end of the twin cassette leads into the EAR and MIC sockets of the cassette recorder. Push firmly home and twist slightly to get good connections. Take the same colour plug 442 as is in the EAR socket of the cassette recorder and place it in the Spectrum EAR socket. Place the other in the MIC socket. Inset the Jack-plug leading from the power supply into the socket marked 9 V d.c. on the back of the Spectrum. Connect the TV aerial/antenna lead to the aerial socket of the TV. Your system is now set up. Check the ТУ is turned off, and no cassette keys are depressed. Plug the ZX power supply and cassette leads into the a.c. (household) power supply sockets, and switch them on if they have switches. 3 Switch on the TV. Choose a channel with the push button or other channel select control, and tune the TV until the display: (O 1982 Sinclair Research Ltd appears on the screen. Adjust the tuning until the display is clear, and the brightness, contrast and colour (if you're using a colour TV!) controls to get a good picture without it being too bright (since you are going to spend some time looking at it from close up). Note for U.S. users: In the U.S., the antenna lead connects with standard terminals to the TV. An antenna on/off switch is provided between the computer and the TV. The computer has a channel select switch to select channel 2 or 3. Whichever channel is not transmitting should be selected, and the TV tuned until the computer display is obtained. 4 Press a few keys to get some characters printed on the screen — these should appear at the bottom of the screen. Then press the CAPS SHIFT and 1 (EDIT) keys together, to clear the screen. 5 Press the Z key. The screen will print COPY at the bottom. Then press ENTER. The printer will start operating, feeding paper through. There will be nothing printed on it because there is nothing printed on the screen. Check that the printer paper does not rub against the side of the printer as it is fed through. If it rubs, pull it gently away from the side as the paper is fed through. You now have an operating microcomputer system. The system needs no maintenance other than the occasional cleaning of the printer and the tape heads on the cassette player. Clean the printer with a small brush to clear away the black dust that accumulates. Be careful not to damage the electrode (a small piece of wire running in the slot visible when the paper carrier is removed). Blow away the dust when you've brushed it from this slot. Keep your cassette tape heads clean and de- magnetised. If the printer doesn't work, first turn off the power. Then remove and re-insert the printer socket. Switch the power on again and try once more. The contacts on the printed circuit boards that the printer 443 socket connects with may need cleaning if the printer doesn't work or prints incorrectly. Clean the contacts with a proprietary contact cleaner or a pencil eraser. DO NOT use abrasives to clean these contacts. These are the only problems you should encounter with your system, as long as all plugs are well seated in their sockets. With the need to remove and re-insert the EAR socket when saving programs on cassette tape, you must take care to always re-insert the jack-plug properly each time. THE KEYBOARD The Spectrum keyboard has 40 keys arranged in 4 rows of 10. At first sight, it might appear similar to a typewriter keyboard, but on closer inspection you will see that keys have 5 or 6 functions or characters. In fact: Eight different characters and functions can be obtained with some keys! The keyboard contains: 1 The digits 0 to 9 2 The letters of the alphabet printed in upper and lower case (capitals) 3 The complete BASIC language: — instructions — commands — arithmetic, conditional and logical operators — arithmetic functions 4 Grammatical signs and symbols 5 Special control keys 6 Graphics symbols These are all called characters, and are on, below or above the keys used to access them. Notice that words like PRINT, LIST, RUN, etc are all printed on the keyboard and also appear on the screen with a single key press. The Spectrum’s ability to print complete words in the BASIC language at the press of a single key is called: SINGLE KEYSTROKE BASIC On most other computers you have to key in each letter of, for example, the instruction PRINT. This is obviously inefficient. The Spectrum is very powerful in this respect. The keyboard contains all the characters in the Spectrum’s character set, together with a few special keys. Some 200 ог so different characters are available. Some print to the screen, others are non-printing (e.g. DELETE). 444 CUP BLUE RED MAGENTA GREEN pn "S LOW m BLACK EDIT CAPS LOCK TRUE VIDEO INV. VIDEO GRAPHICS DELETE 17 2 9 Rt RUP T ` „Лл в d Her DEF FN OPEN я CLOSE * MOVE ERASE POINT CAT г. ae c LA 0 E о БАЯ Mus R Á J; ы» IU VERIFY MERGE ES DATA AF i su ы ғ oe ENTER | sm oe Ht ЖӘ K CIRCLE VAL$ SCREEN$ а |с? UN B N M E ЕЗ | SPACE ЕР 2 oe и> C 2 V: Z Bs М os ЕЗ | SPACE PAPER FLASH BRIGHT OVER ANVSOVIO a WNYLIAdS r aunbi4 THE CHARACTER TYPES ON THE SPECTRUM KEYS The Spectrum keyboard, to handle the enhanced version of Sinclair BASIC that runs on the Spectrum, has to accommodate more functions. This has been done by using basically the same layout as the ZX81 keyboard, but incorporating an additional shift key, which provides the capacity to access the additional colour, graphics, sound and microdrive functions which are present on the Spectrum but not on the ZX81. The Spectrum has an enhanced character set also, with additional text characters (@, ©, [, ],~, etc.) not in the ZX81 character set. As this book deals with the ZX81 computer as well as the Spectrum, the treatment of additional facilities of the Spectrum is kept to this separate Spectrum Section, although some comments are made in the general text about these facilities where appropriate. However, you must learn how to access all the characters on the keyboard as a first priority. The keyboard is very complex and it will take some time for you to find your way around it with ease. It is best described in terms of how the characters are accessed and the cursors that indicate which mode the computer is in. The mode determines how the pressing of a key (a keystroke) is interpreted. Each key has multiple meanings for the computer, depending on the mode and whether either of the SHIFT keys (CAPS SHIFT and SYMBOL SHIFT) is being pressed at the same time as the keystroke occurs. You will notice that more characters are available from the top row of keys. These incorporate the colour control and graphics characters. (The inverse graphics are not shown on the key.) Here are examples of the two types of key: E Mode CAPS SHIFT CAPS SHIFT BLUE %- COLOUR CONTROL CHARACTER CHARACTER EDIT (in appropriate colour) (white) G Mode. Unshifted eh —— Graphics Character K and MODES G Mode Shift gives UNSHIFTED DIGIT Inverse Character ( IK in this case) CHARACTER K and L Modes SYMBOL SHIFT CHARACTER (red) E Mode SYMBOL SHIFT CHARACTER (Red) ROW 7 KEYS Example is the 1 key 446 / E Mode UNSHIFTED CHARACTER (green) SIN L Mode UNSHIFTED жей K апа L Modes SYMBOL LETTER CHARACTER —> Q (= | - SHIFT CHARACTER (lower case) PLOT <. K Mode UNSHIFTED CHARACTER CHARACTER (upper case) ^ E Mode SHIFT CHARACTER (red) OTHER KEYS Example is Q key There are also the keys for ENTER, CAPS SHIFT, SYMBOL SHIFT, and the SPACE key (with BREAK printed above SPACE). See the keyboard diagram. We must now describe the modes the computer can be in, and the cursors that indicate the mode. There are also two other cursors which we will deal with here. MODES When inputting (keying in) program lines the position for the next entry is indicated by a cursor on the screen. The mode is indicated by the flashing cursors [E] . The mode (Keywords) and (Letters) may be used unshifted, with CAPS SHIFT or with SYMBOLS SHIFT. Letters of the alphabet are lower case unless the CAPS SHIFT key is used or the mode used. The mode (Capitals) is obtained by pressing CAPS SHIFT and CAPS LOCK simultaneously and is identical to the L mode apart from producing capitals (upper case) instead of lower-case letters. To return to mode press CAPS SHIFT and CAPS LOCK simultaneously. All letter inputs (REM statements, string inputs and assignments) in this text are in Capitals. You must use C-mode exclusively to get listings and printout of letters that correspond to those in this text. The mode (Graphics) accesses the graphics characters and may be obtained using the GRAPHICS key as an on-off switch. Press CAPS SHIFT and GRAPHICS simultaneously to enter mode. Repeat to cancel. 447 The mode (Extended) provides the equivalent of the function mode of the ZX81. It is obtained by pressing CAPS SHIFT and SYMBOLS SHIFT simultaneously and lasts for one character only. It may be used unshifted, with CAPS SHIFT or with SYMBOLS SHIFT. EFFECTS OF SHIFT KEYS ON MODES K mode — expecting a command i.e. Keyword mode. Unshifted - keyword (white word оп 3 bottom rows of keys) — digit (white digit on top row of keys) CAPS SHIFT - keyword (white word on 3 bottom rows of keys _ a ЖР (white word above top row of keys) SYMBOLS SHIFT - keyword or symbol (red symbol or word on key) L, mode — expecting a letter or a number i.e. Letters mode, giving the lower case letters. Unshifted — letter (white letter on 3 bottom rows of keys) — digit (white digit on top row of keys) CAPS SHIFT — letter (capitals) (white letter on 3 bottom rows of keys) — keyword (white word above top row of keys) SYMBOLS SHIFT - keyword or symbol (red symbol or word on key) C mode — identical with L mode but Capital letters are obtained with Unshifted letter keys. G mode — for accessing Graphics symbols. Unshifted — graphics character (in grey/white on keys 1 to 8) — user defined graphic on keys A through U. (Not shown on keyboard.) CAPS SHIFT — inverse graphics character (reverse of symbol on top row of keys) SYMBOL SHIFT — same as CAPS SHIFT User defined graphics are dealt with in Unit W2. They are initially set as the capital letters À to U, which is what appears on the screen. 448 Note that DELETE works in G mode without CAPS SHIFT being pressed. E mode - Extended mode, accessing the function characters in green above the keys in bottom 3 rows, colour control characters on the top row,and the function or symbol characters in red below all keys. E mode lasts for one character only. Unshifted — function or symbol (in green above key for 3 bottom rows) — colour control (in colour above top row) CAPS SHIFT — function or symbol (in red below key for 3 bottom rows) — colour control (in colour above key for top row) SYMBOLS SHIFT -function or symbol (in red below key for 3 bottom rows) — function (in red below key for top row). The colour control characters print in a program line as the digit of the key that accesses them, i.e. they are coded 1-7 and 0. If they are accessed in E mode without INK or PAPER before them, the effect is to put colour control characters into the display. When unshifted, the colour control characters change the background (PAPER) colour of what is placed on the screen thereafter, and when CAPS SHIFT is pressed, the colour of the character (INK) is changed. Note: the main body of this text assumes no colours are used, since the ZX81 cannot produce colour. Colour on the Spectrum 15 dealt with in Unit W3. Experiment with colour all you want, but this text is primarily about BASIC programming, and it doesn’t matter what colour is on the screen for this! Exercise Access all the modes, 1.е. get each different cursor on the screen. Key in all the characters in each mode, first unshifted, then with CAPS SHIFT, and finally with SYMBOL SHIFT. You will have to enter the E mode again after each character. Watch what happens with TRUE VIDEO and INV VIDEO. Notice they reverse each other. Notice you can’t see a SPACE. Don’t press ENTER, just play around on the bottom lines of the screen. Notice that the line moves up the screen when it is filled. Press EDIT with CAPS SHIFT to clear the screen. You can’t harm the computer whatever you enter. Note that two words are abbreviated on the keyboard, but print in full- RAND and CONT. 449 SYNTAX ERROR CURSOR This cursor appears flashing in a line input at the bottom of the screen if the computer detects an error in the syntax of the line (i.e. finds an error in the ‘grammar’ of the BASIC language instruction input). It appears when ENTER is pressed to enter the line of program or the command into memory. The cursor appears before the last error in the line. There may be more than one error, but only one will be indicated at a time. Editing (making any change in the line) causes the cursor to disappear. It will reappear if necessary (error not corrected) when ENTER is pressed once again. CURRENT LINE CURSOR > This cursor appears after the line number of the last line entered into a BASIC program (the current line). If EDIT is pressed (CAPS SHIFTed 1) this line is brought down to the bottom of the screen. It can then be edited. In a program listing of the lines of a program displayed on the screen, the cursor may be moved to point to different lines by using the (CAPS SHIF Ted 6) and (CAPS SHIFTed 7) keys to move it down or up a program line. This is used to select a line for editing. An important point to note with regard to the keyboard is that the Spectrum has a repeat key action on all keys. If any key is held down, after a short time it will automatically repeat. We now give a table of the characters accessible on the Spectrum keyboard. Ignore the CODE information for now. This will be dealt with later. This table is the Spectrum equivalent of Appendix III, which deals with the ZX81. CHARACTER SET AND CODES TABLE This table, which is in alphabetical order, will enable the Spectrum user to quickly reference any character for: — its position on the keyboard in terms of a row and column ‘parent key’ address (e.g. A is in the third row and first column of keys (3,1)) — the mode in which the function may be used (indicated by the flashing cursor on the screen) — which keys to press to obtain the function (here SHIFT means that ether the CAPS SHIFT or the SYMBOL SHIFT key will give the character) — the CODE of the character. 450 Character BEEP BIN BORDER BREAK BRIGHT C C CAPS LOCK CAPS SHIFT CAT CHR$ CIRCLE CLEAR CLS CODE CONTinue COPY COS D d DEF FN DELETE DIM DRAW Position on Keyboard Row, Column 3,1 ` - ` ` ~ ` Q3 NO NON h2 h2 CO CO О S OO — O N Oe ` Mode(s) L C LC Aidt г сг mmm t= — шлш i p, EA г Gy E": ОО LC о О AR дагог 451 QQ To Obtain Press CAPS SHIFT SHIFT SYMBOL SHIFT SHIFT SYMBOL SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT SHIFT CAPS SHIFT CAPS SHIFT SYMBOL SHIFT SHIFT CAPS SHIFT SYMBOL SHIFT CAPS SHIFT CAPS SHIFT CAPS SHIFT ENTER SYMBOL SHIFT rh — O < z Q > > > = = tN 2 % о CAPS SHIFT SPACE = ZU9e-puU жыс-<мшао NOOO — m tm tz pa ^! Code Character Position Mode(s) To Obtain Code on Keyboard Press Row, Column F 3,4 L CAPS SHIFT F 70 C F Í 3,4 L F 102 FLASH 4,5 E SHIFT Ұ 72% ЕМ 1,2 Е SYMBOLSHIFT 2 168 FOR 3,4 K F 235 FORMAT 1,10 E SYMBOL SHIFT 0 268 G 3,9 L CAPS SHIFT G 71 C G g 3.9 L С 103 GOSUB 3,6 K а ЖИ GOTO 3,5 K G 236 GRAPHICS 1,10 KLC CAPS SHIFT 0 - H 3,6 L CAPS SHIFT H т C H h 3,6 L H 104 I 2,8 L CAPS SHIFT I 73 C I i 2,8 L I 105 IF 2,7 K U 250 IN 2,8 E SHIFT I 191 INK 4,3 E SHIFT АЖА 217 INKEY$ 4,7 E N 166 INPUT 2,8 K I 238 INT 2,4 E R 186 INVERSE 4,8 E SHIFT M 221 J 3,7 L CAPS SHIFT J 74 C J j ы 2 L J 106 K 3,8 L CAPS SHIFT К 75 C K k 3,8 L K 107 L 3,9 L CAPS SHIFT L 176 C L 1 3,9 L L 108 LEN 3,8 E E іл LET 3.9 K L 241 LINE 3,9 K L 202 LIST 1,3 K K 240 LLIST 4,5 E V 225 LN 4,2 Е 2 184 LOAD 2,7 K J 239 LPRINT 4,4 E C 224 M 4,8 L CAPS SHIFT M 77 C M m 4,8 L М 109 452 Character Position Mode(s) To Obtain Code on Keyboard Press Row, Column MERGE 2,9 E SHIFT £ 213 MOVE 1,6 E SYMBOLSHIFT 6 209 N 4,7 L CAPS SHIFT N 78 C N n 4,7 L, N 110 NEW 3,1 K A 230 NEXT 4,7 K N 243 NOT 5,2 KLC SYMBOLSHIFT S 195 O 2,9 L, CAPS SHIFT O 79 C O о 2,9 L O 111 OPEN 1,4 E SYMBOLSHIFT 4 211 OR 2-7 KLC SYMBOLSHIFT U 197 OUT 2,9 Е SHIFT O 223 OVER 4,7 E SHIFT N 222 P 2,10 L CAPS SHIFT p 80 C P 2,10 L P 112 PAPER 4,4 E SHIFT C 218 PAUSE 4,8 K M 242 PEEK 2,9 E O 190 PI 4,8 E M 167 PLOT 2,1 K О 246 POINT 1,8 E SYMBOLSHIFT 8 169 POKE 2,9 K О 244 PRINT 2,10 K P 245 о Д.Т L CAPS SHIFT О 81 С Q q 2,4 L Q 113 R 2,4 L CAPS SHIFT R 82 C R r 2,4 L R 114 RANDomise 2,9 K % 249 READ 3,1 E ‚А 227 REM 2,2 K E 234 RESTORE 2,4 Е 5 229 RETURN 2,6 K Ү 254 RND 2,0 E Ж 165 RUN 2,4 K R 247 S 2,2 L CAPS SHIFT S 83 C S S 3,4 L S 115 SAVE 2,2 K S 248 SCREEN$ 3,8 E SHIFT K 170 SGN 3,4 E F 188 SIN 2.1 Е Q 178 SPACE 4,10 SPACE 22 453 Character SQR STEP STOP STR$ SYMBOLSHIFT N N WOOnNO сл > оо FS Ke © Position on Keyboard Row, Column 42 - м “ м » EJ ` EI к. — к л — һа ка ка ка — о О-О OF ы OO м = = - L C L C СӘС шшш бу Brot > > D m t Ca Es С сы DOE 454 To Obtain Press SYMBOLSHIFT SYMBOLSHIFT SYMBOL SHIFT CAPS SHIFT SYMBOL SHIFT SYMBOL SHIFT CAPS SHIFT CAPS SHIFT SHIFT SHIFT CAPS SHIFT CAPS SHIFT CAPS SHIFT CAPS SHIFT «wie Мих се: AS edie асс "obw < > Ü NNN ос со м СУ Q > ON © Code Character Position Mode(s) To Obtain Code on Keyboard Press Row, Column ! 1,1 KLE SYMBOL SHIFT 1 33 с 2,10 ELE SYMBOL SHIFT P 34 # 1,3 KLG SYMBOL SHIFT 3 35 $ 1,4 KLE SYMBOL SHIFT 4 36 % 1,5 ELO SYMBOL SHIFT 5 37 & 1,6 KLG SYMBOLSHIFT 6 38 ; 1,7 ELE SYMBOL SHIFT 7 39 ( 1,8 KL O SYMBOLSHIFT 8 40 ) 1,9 K LO SYMBOLSHIFT 9 41 * 4,6 ELO SYMBOLSHIFT B 42 4 3.8 EIL SYMBOLSHIFT K 43 | 3,6 ELO SYMBOLSHIFT H 44 © 4.7 KLC SYMBOLSHIFT J 45 4,8 ELS SYMBOLSHIFT M 46 / 4,5 KLE SYMBOL SHIFT V 47 4,5 ELO SYMBOLSHIFT Z 58 : 2,9 É L O SYMBOLSHIFT O 59 < 24 ELC SYMBOLSHIFT R 60 » 3.9 KLC SYMBOLSHIFT L 61 » 2.5 KI SYMBOL SHIFT T 62 ? 4,4 ELE SYMBOLSHIFT C 63 Q 4,2 ELG SYMBOL SHIFT 2 64 ( 26 Е SHIFT Y 91 ) > 7 E SHIFT W 93 % 3.3 E SHIFT D 92 ^ 3.6 ELO SYMBOLSHIFT H 94 a 1,10 KLC SYMBOLSHIFT Q@ 95 £ 4,3 ЕЗІ SYMBOLSHIFT X 96 i 3.4 E SHIFT F 193 | 3,5 Е SHIFT G 195 | 2,3 E SHIFT S 124 ~ 3.1 E SHIFT A 126 © 2,10 E SHIFT P 1⁄2 ы 2,1 KLC SYMBOLSHIFT Q 199 S 2.3 ELG SYMBOL SHIFT E 200 <» 2,2 ELC SYMBOL SHIFT W 201 ate 1,5 EL CAPS SHIFT 5 8 кч 1,8 ELO CAPS SHIFT 8 9 V 1,6 K L G CAPS SHIFT 6 10 À 1:7 K LL G CAPS SHIFT ?. 4d | |] (space) 1,8 С 8 128 Бы 1,8 G SHIFT 8 143 k 1,1 с 1 129 k= 1,1 G SHIFT 1 142 Е | 12 G 2 136 v 1,2 G SHIFT 9 141 - i G 4, 191 - 1,3 G SHIFT 3 140 [m 1,4 G 4 132 ГЕ 1,4 G SHIFT 4 139 ГЕ 1,5 G 5 133 H 1,5 G SHIFT 5 488 " 1,6 G 6 134 455 Character Position Mode(s) To Obtain Code on Keyboard Press Row, Column m" 1,6 G SHIFT 6 137 " 1,7 G 7 135 B 1,7 G SHIFT 7 136 Colour control characters have no special codes. They have the codes of, and print as, the digit of the key that accesses them. They are on keys 1 to 7 and 0. TRUE VIDEO is on key 1,3. This gives INK on PAPER colours (black on white on switch-on). INV. VIDEO is on key 1,4. This gives INVERSE, i.e. PAPER colour on INK colour background (white on black if not coloured). These use CODE 20 (a control code), and swap the current INK and PAPER colours. Other control codes are as follows: Control Character Code Comma for print spacing 6 Number (in memory) 14 Ink control 16 Paper control 17 Flash control 18 Bright control 19 Inverse control 20 Over control 21 Print At control 22 Print Tab control 23 These control characters are used to store required information in the attribute file (colour commands and characteristics of screen display), and the display file. They are followed by the values they take. User-defined graphics have codes 144 to 164 inclusive, and are set, unless redefined, as the capital letters À to U in sequence. See Unit W3 for more information on this. W2: Additional Spectrum BASIC Functions This Unit covers the additional instructions and functions that are avallable in the Spectrum superset of Sinclair BASIC. First we will indicate the major differences. 456 SUMMARY OF ADDITIONAL SPECTRUM FACILITIES The following are the significant differences between the ZX81 and the Spectrum which have not been dealt with in the main body of the text: (1) (ii) (iii) (iv) (v) (vi) (vii) (viii) (ix) (x) (xi) The Spectrum gives a colour signal to the TV - see COLOUR in Section W3. Of course, it is still possible to use the machine on a black and white TV, where different shades of grey will be obtained when the colour commands are used. The Spectrum's character set differs from that of the ZX81 and includes lower case as well as capital letters- see CHARACTER SET and USER DEFINED GRAPHICS. The Spectrum's keyboard has additional characters and functions. You should now be familiar with the functions treated in the main text. Extended functions are dealt with a little later in this Unit. Simple sound production is available using the Spectrum's BEEP command - see SOUND in Section W3. The tape storing facilities represent a considerable improvement on those offered by the ZX81- see TAPE STORAGE below. The tape LOAD and SAVE speed is roughly 16k words in 100 seconds, and there is a facility to merge a program stored on tape with one in memory using MERGE. The VERIFY facility can be used to check that a program has saved correctly, as has been noted. Disc storage and file-handling capability with the microdrive will eventually be available on the Spectrum, loading 16k words per second - see OTHER KEYS below. Additional graphics commands are available to enable straight lines, arcs and circles to be drawn simply - see GRAPHICS in Section W3. The INPUT statement has additional features and instructions. READ, DATA and RESTORE are added - see below: PUTTING DATA INTO PROGRAMS. On the Spectrum it is possible to define your own numeric and string functions in а program -see USER DEFINED FUNCTIONS below. The Spectrum operates in a ‘fast mode’ at all times and is roughly four times faster than the ZX81. Multiple statements on a line are possible on the Spectrum with a colon(:) as a statement separator. For example: 10 LETX-4:LETY26: LET Z=8 Whilst this is a useful addition, multiple line statements can also be very confusing and their use should be minimised. This said, they can be useful for additional REM statements, assignments of related variables and conditional program sequences, and for the combination of graphics and colour commands. 457 The facility of being able to place a sequence of instructions after a conditional test is valuable. The sequence of BASIC Instructions following an IF...THEN will be executed IF the condition is TRUE. Control passes directly to the next line of the program if the condition is false. We can write: 10 INPUT å 20 IF а<1 OR a>9 THEN PRINT “Out of Range’’: GOTO 10 30 PRINT a It is important to remember that you can only GOTO a line number and start at the beginning of that line. You cannot access the second or subsequent statements of a line with multiple statements. (xii) There is no SCROLL key on the Spectrum, but scrolling is done automatically by pressing any key (except N, STOP, BREAK) when ‘Scroll?’ appears on the screen. Making the Spectrum SCROLL in the same way as the ZX81 SCROLL command has been covered in the text. (xiii) It is important to note that CLEAR operates differently on the Spectrum than on the ZX81. CLEAR not only erases all variables in memory, but also resets RAMTOP апа RESTORE s as well as clearing the GOSUB stack. In fact you can use CLEAR on the Spectrum to reserve protected memory space above RAM TOP: using a command like CLEAR 23800 sets RAMTOP to 23800. This cannot be done on the ZX81. You have seen the modifications required for the ZX81 programs to run on the Spectrum. Here is a summary for reference, to convert any programs you may come across in books or magazines. All programs in the text and the program library (Appendix VI) are annotated with any required Spectrum changes. ZX81 TO SPECTRUM PROGRAM CONVERSION There are relatively few things to bear in mind when converting a ZX81 program for the Spectrum. Of course, the ZX81 will not have included colour or sound in the programs, and these are aspects you can add for yourself. Note that ZX81 programs SAV Ed on cassette will not load into the Spectrum, even if no ZX81 specific commands have been used. Perhaps the first thing to note is that you must be in CAPS mode to produce listings and programs which are identical to those of the ZX81. (Use CAPS SHIFT with CAPS LOCK to stay in this mode when you switch on.) PLOT plots in high resolution — 256 x 176 pixels — whereas on the ZX81 the resolution was only 64 x 44. Thus as a general rule you сап 458 simply multiply by a factor of four to any PLOTted points in a ZX81 program to obtain a working Spectrum version. Hence PLOT 4,10 on the ZX81 becomes PLOT 16,40 on the Spectrum. The Spectrum has no FAST and SLOW modes, as it runs in the equivalent of the SLOW mode all the time (always a screen display) but at the speed of a fast mode. Just omit program lines that contain the instructions FAST or SLOW. The Spectrum does not have SCROLL as a program instruction as the ZX81 does. To SCROLL the screen in a Spectrum program you need to POKE the location 23692 with a number greater than 1, or with —1. This temporarily disables the ‘SCROLL?’ request, and when followed by PRINTing AT the last line (line 21) on the screen the display will SCROLL. Thus the ZX81 line: 200 SCROLL is replaced by 200 POKE 23692, – 1 : PRINT AT 21,0; Raising a number to a power on the ZX81 uses the symbol ‘**’ whereas on the Spectrum we use ‘ ^". RAND іп ZX81 programs is that instruction on the Spectrum keyboard, but prints as RANDOMISE. POK Eing to the display file cannot be easily done, and the same is true of PEEK used to identify a character on the screen. To get around this we recommend using PRINT AT instead of POKEing the display, and SCREENS to replace PEEKing the display. Hence you will have to calculate what character cell position corresponds to any address in the ZX81's display file which is used in a program. Read the description of the ZX81 display file in Unit Q4 in order to find out how to do this. PEEKing the character table in RAM is done equally simply on the Spectrum, with the start of the character table being given by the following PEEKs, plus 256: PEEK 23606 + 256* PEEK 23607 This is usually set at 15360 — but you can POKE these addresses and change the location at which the character table starts in memory. You can therefore create an entirely new character set in RAM and have the CHARS variable (stored in the locations above) point to 256 bytes below it. All other system variables on the ZX81 have equivalents on the Spectrum. This text has the system variables for both machines listed in Appendix V. Because of the amount of memory (6.5k) taken up for graphics on the Spectrum, you will find that a large program for the 16k ZX81 (of 10k or so), will not fit into a 16k Spectrum. 48k Spectrum owners will of course have no problems with this, but if contemplating keying in a 459 long program with the smaller machine it is worth making a crude estimate of the program length, if the information is not given in the documentation. The number oflines in the listing (total, not numbered lines only), multiplied by 15 will give you a reasonable estimate (biased on the high side) of the program length in bytes. We will now go on to cover the additional Spectrum facilities and functions, other than those connected with Colour, Graphics and Sound, which are treated in Unit W3. TAPE STORAGE New keywords: VERIFY and MERGE. Associated new keywords: LINE, DATA, SCREEN$ (1) SAVING Information on Tape The SAVE key is used to save information on tape. This can be: (a) program and variables, (b) arrays, (c) bytes of memory (memory contents) When saving information on tape it is essential that the EAR piece jack- plug 15 removed from the tape recorder. (a) Programs and Variables SAVE ‘‘filnam’’ - saves programs and variables. SAVE ''filnam" LINE 10- saves programs and variables and when loaded next automatically runs itself from the given line number. (b) Arrays SAVE “alpha” DATA а()- вауев the numeric array а specified under the name alpha. SAVE “beta” DATA b$()-saves the string array b$ specified under the name beta. (c) Bytes SAVE “gamma” CODE 16384, 6912- saves the bytes specified. The first figure (in this case 16384) is the address of the first byte to be saved and the second figure (in this case 6912) is the number of bytes to be saved. The particular bytes specified above will save the ГУ picture, but a special key SCREENS is available to do this: SAVE ‘‘gamma’’ SCREEN$ 460 (i1) (iii) VERIFICATION of Information on Tape The VERIFY key is used to check the information saved on the tape against the information in the computer. VERIFY ‘‘filnam’’ - checks programs and variables VERIFY “аірһа” DATA a()-checks numeric array specified VERIFY “beta” DATA b$()-— checks string array specified VERIFY “сапта” CODE 16384, 6912 – checks bytes specified (first number – address of first byte, second number - number of bytes). LOADING Information from Tape The LOAD key is used to load new information from the tape, deleting any old information in the memory. LOAD ''filnam'' -loads program and variables specified (and automatically runs the program if the SAVE and LINE instructions were used to save the program). LOAD “alpha” DATA a() - loads numeric array specified by alpha as array a in memory. LOAD “Бега” DATA b$() - loads string array specified by beta as array b$ in memory. (N.B. If insufficient memory is available, an error message occurs and the old information in memory is not deleted.) LOAD “сатта” CODE 16384, 6912 loads the bytes specified (first number is the address of the first byte, second number is the number of bytes). LOAD “gamma” SCREENS is an alternative for the particular bytes specified above which contain the TV picture. (iv) MERGING Programs The MERGE key is used to combine a program already in memory with a program on tape (it may not be used on arrays or bytes). MERGE ‘‘delta’’ — adds the program delta (stored on tape) to the program already in memory, overwriting any program lines and variables in memory which are at the same line numbers or have the same variable name as those on tape. For example: Program in memory: 10 PRINT “hello” 20 PRINT 30 PRINT ‘‘goodbye’’ 40 PRINT 50 PRINT “ела” 461 Program ‘‘delta’’ on tape: 19 PRINT "no" 20 PRINT “уез” 60 PRINT ‘‘repeat’’ MERGE “delta” results in the program: 10 PRINT “по” 20 PRINT “yes” 30 PRINT ''goodbye" 40 PRINT 50 PRINT “епа” 60 PRINT ‘‘repeat’’ Note the restriction on the use of MERGE. It can only be used for numbered program lines. These can have defined arrays or variables that are transferred with the program, but direct data (array values or bytes) is not MERGEable. See Units T11 and T12 for storing data, and remember that as long as there is one program line, MERGE will work. PUTTING DATA INTO PROGRAMS New keywords: READ, RESTORE and DATA Extended function for INPUT key (1 INPUT Statement 10 INPUT A$ allows input of one string 20 INPUT A,B,C,D allows input of four numbers 30 INPUT ‘‘Enter your name’’, N$ allows the part within inverted commas to be printed at the bottom of the screen. If we key in: 10 LET M$ =‘‘SPECTRUM’’ 20 INPUT (‘‘I am’’;m$;‘‘.’’); ‘‘Your name?’’, y$ these two lines will produce at the bottom of the screen: I am SPECTRUM. Your name? “ cursor ” It is also possible to use INPUT AT in a similar way to PRINT AT: 10 DIM a$(5) 20 INPUT АТ 0,0; a$(1); АТ 1,0; a$(2); AT 2,0; a$(3); АТ 3,0; a$(4); АТ 4,0; а%(5). 462 (11) (iii) This will result in the inputs being placed on separate lines (note what these co-ordinates mean). The lower part of the screen will move up to allow all input lines to be on screen. (The upper part remains unaltered until the lower part would start to write on the same line — the upper part then starts to scroll.) 10 INPUT LINE a$ allows input of a string without the computer inserting quotes around the cursor. READ and DA TA These keys allow data to be stored internally within the program. For example: 10 READ a,b,c 20 PRINT a,b,c 30 DATA 10,20,30 The computer looks at all lines containing DATA statements and puts them sequentially into a data bank. A pointer is associated with the data bank and is initially set to the first item. 10 20 30 ^ When the program reaches a line with a READ statement, the first data item is allocated to the variable (i.e. a = 10) and the pointer moves to the second item and so on. So b = 20 and c= 30. Note (i) DATA items are separated by commas (1) variables in READ statements are separated by commas (ii) string data items must be in inverted commas For example: 10 READ a$,b,c$,d 20 PRINT a$,b,c$,d 30 DATA ‘‘smith’’, 90 40 DATA ‘‘jones’’, 60 RESTORE The RESTORE statement may be used to alter the position of the pointer. For example: 10 READ a$,b 20 RESTORE 30 READ c$,d 463 40 PRINT a$,b,c$,d 50 DATA ‘‘smith’’, 90, ‘‘jones’’, 60 The effect of line 20 is to reset the pointer to the first item. Thus a$ = ‘‘smith’’, b = 90, c$ = ‘‘smith’’, d = 90. It is also possible to use RESTORE with a line number in which case the pointer is reset to the first item of the data statement of that line (or following lines). For example: 10 READ a$,b 20 RESTORE 100 30 READ c$,d 40 PRINT a$,b,c$,d 50 DATA ''smith'', 90, ‘‘jones’’, 60 100 DATA ‘‘brown’’, 100, ‘‘white’’, 120 200 DATA ''black'', 8, '*yellow'', 6 This will allocate a$ = “smith”, Ь-90 and c$ = “brown”, а= 100 (whereas 20 RESTORE gives c$ = smith", d = 90 and 20 RESTORE 200 gives c$ = ‘‘black’’, d = 8). If CLEAR is used on the Spectrum, it also does a RESTORE on the data. USER DEFINED FUNCTIONS New keywords: DEF FN and FN The user can define up to 26 numeric and 26 string functions in any program. A numeric function is named FN followed by a single letter — e.g. FN Z. A string function is named FN followed by a single letter and $ – e.g. FN A$. It is necessary to define the function using a DEF FN statement (i.e. by pressing the DEF FN key). For example: 10 DEF FN а(х)-х%3 20 PRINT FN a(3) Line 10 defines the function and line 20 would give 3° = 27. For strings: 10 DEF FN q$(a$) = a$ (2 to 6) 20 PRINT FN q$(‘‘harrison’’) Line 10 defines a string function and line 20 would give ‘arris’. You may also use functions with several variables: 464 5 LET a=10: LET b= 20 10 DEF FN p(x,y,z) =а*хфћ 2 +ЬЪ*ућ 2+2 20 PRINT FN p(1,2,3) 30 PRINT 40 PRINT FN p(3,2,1) Note that any constants occurring (in this case a,b) are not included in the FN; only the variable values are specified (in this case x, y and z). Thus line 20 gives 93 and line 40 gives 171. CHARACTER SET AND USER DEFINED GRAPHICS (1) Character Set The character set consists of 256 characters each having a code between @ and 255. The set consists of: Control characters (code 0 to 31) ASCII characters (plus the non-standard £ and ©) Spectrum graphics symbols User-defined graphics The program given below will print out the complete character set (excluding the control characters): 10 FOR n=32 ТО 255: PRINT CHR$ n;: NEXT n (ii) User defined graphics These are the letters A to U in graphics mode. They initially print as these letters (in capitals), until defined. They enable one to print a given shape in a character cell by pressing a single key. EXAMPLE: Fill the screen with dogs. Begin by producing a dog shape which fills a character cell when GRAPHICS D is pressed and then display the dogs across the screen. (1) Fill in appropriate squares in 8 by 8 cell (11) Allow 1 for ink, 0 for paper (ui) Put appropriate numbers in data statements Binary Decimal жа жк l l ` dx 11100001 225 11100010 226 11111100 252 00111100 60 00111100 60 00111100 60 00100100 36 00100100 36 465 со PORE USR 2 2 Ж Se NEXT n _ (: то DATA 25,226, 252,52, Ба, еб, З Б ЗР -- z | p 20 REM screenfFut of dogs эр BORDER а: POPER 2: INK е: LC LS ip FOR ісе TO ге STEF 2 лла FOR c=@ ТО за STEP = 15а PRINT BT ipi 130 NEXT с 142 NEXT £ The BIN key allows you to enter binary numbers —1.e. BIN 11100001 is equivalent to 225 in the DATA statement (line 65). The plot of the user-defined graphic in the 8 x 8 grid, expressed in binary form, can thus be centred directly with the use of BIN into the DATA statement: 70 DATA BIN 11100001, BIN 11100010, etc. OTHER KEYS The following keys will only operate when the Sinclair microdrive and the RS 232 (standard printer) interface become available: OPEN ж, CLOSE * , MOVE, ERASE, CAT and FORMAT. The keys IN and OUT are associated with I/O ports (input and output ports) and enable the SPECTRUM to communicate with peripheral devices. The equivalent commands used by the operating system run the ZX Printer. They are beyond the scope of the present text. The use and format of these instructions will be specified in the documentation of any equipment using them. W3: Colour, Graphics and Sound COLOUR (i) BORDER AND PAPER The screen is divided into two areas referred to as: BORDER (the outer part) and PAPER (the central area). (24 lines of 32 characters.) The instructions BORDER and PAPER are used to define the colours of the areas. The following colours are available: ) black 1 blue 466 (11) red magenta green cyan yellow white -] OQ) ол © h2 Magenta is a purple colour, and cyan is light blue. Unless otherwise specified, both BORDER and PAPER are white. The colour of border and paper can be changed to any of the eight normal colours. For example: BORDER 4: the border becomes green on pressing the ENTER key PAPER 2: no change occurs on pressing the ENTER key (it merely cancels PAPER command already existing). Press the ENTER key again and the centre becomes red. (On a black and white ТУ the above numbers correspond to the order of brightness). Both instructions can be used in programs: 10 BORDER 2: PAPER 6 These are global commands defining the whole border and paper areas. PAPER may be used as a specific command (see below). PICTURE The picture area affected by the global PAPER instruction consists of 24 lines each of 32 positions, i.e. 24 x 32 = 768 character cells. The screen that can normally be printed to is 22 lines of 32 character cells. The character cells have printing characteristics (attributes) which may be specified. Each character cell consists of 8 x 8 dots and has two colours associated with it: INK (foreground colour) PAPER (background colour) Normally each character cell has black ink and white paper. In addition, each character cell also has а brightness attributed with BRIGHT (normal ог extra-bright) cor- responding to BRIGHT 0 and BRIGHT 1 and the attribute FLASH with the possibility of no-flash or flash corresponding to FLASH 0 and FLASH 1. For example: 10 PAPER3:INK6: BRIGHT 0 : FLASH 1 would result in background magenta, foreground yellow, normal brightness and flashing. Flashing characters alternate 467 (111) the ink and paper colours. In addition, 8 can be used with all four statements meaning transparent (i.e. left as previous); 9 can be used with PAPER and INK meaning contrast. PAPER will be dark (black) if INK 15 specified as a light colour (colours 0 to 3), light (white) if INK specified as a dark colour (colours 4 to 7). INK produces contrasting PAPER in the same way. INVERSE, OVER AND ATTR The statements INVERSE and OVER may also be used to control the dot pattern printed in the character cells. inverse or normal i.e. INVERSE 1 (inverse video) or INVERSE 0 (normal video) over or normal i.e. OVER 1 (overprints the new character on top of the old) OVER 0 (normal) All the statements in (11) and (iii) may be used in conjunction with PRINT and INPUT commands and also with graphics commands such as PLOT and DRAW. For example: 10 INPUT INK 2; FLASH 1; ‘‘What is your name?’’; N$ 20 PRINT PAPER 6; N$ which will result when run in ‘What is your name?’ flashing in red and white and the name input (in black and white) is then printed out in black on yellow. If not specified, the PAPER instruction assumes the contrasting INK, FLASH @ and BRIGHT 0. The attributes of any character cell (i.e. PAPER, INK, BRIGHT and FLASH) on the screen may be determined using the ATTR key, which returns a number made up as follows: FLASH on (128), normal (0) + BRIGHT on (64), normal (Ø) + PAPER (8* colour) + INK (colour) Thus, 10 PRINT ATTR (19,20) would give the number 162 if the character cell at (19,20) is flashing (128), normal (0), green paper (32) and cyan ink (2). The TRUE VIDEO instruction gives the INK colour on PAPER colour background. This may be changed to INV.VIDEO (PAPER colour on INK colour). All succeeding printed character squares have the attributes shifted as if INVERSE had been used. 468 EXAMPLE 1 This is a simple program to display the colours available and to show the effect of the transparency and contrast commands. 5 REM colours 10 FOR п-1 TO 22: FOR p=0 TO 7 20 PAPER P: PRINT " е; 30 МЕХТ р: МЕХТ п 40 PAUSE 100 45 REM transparency апа contra st 50 INK 9: PAPER 6: PRINT AT 0, 0; 60 FOR n=l TO 66: PRINT "colou rings";: NEXT D: PRINT 70 PAPER 7: INK 0: BRIGHT @ 80 PAUSE 100 EXAMPLE 2 This is a simple program drawing coloured straight lines with different separations. Line 30 - gives а black border. Line 320 – gives paper and ink colours (selected at random, excluding black and white). Line 200 - resets paper and border to white, ink to black for listing etc. after program has been run. Notice how colours are character cell dependent not pixel dependent. This program clearly shows this effect. 38 BORDER @ 40 FOR х-й ТО 254 STEP 2 50 PLOT 128,88: DRAW -127+x,-8 7 60 NEXT x 65 GO SUB 300 76 FOR y=0 TO 174 STEP 3 88 PLOT 128,88: DRAW 127,-87+y 90 NEXT y 95 GO SUB 300 100 FOR z=0 ТО 254 STEP 2 110 PLOT 128,88: DRAW 127-z,87 120 NEXT Z 125 GO SUB 300 130 FOR a=0 TO 174 STEP 3 140 PLOT 128,88: DRAW -127,87-a 150 NEXT a 200 PAPER 7: INK 0: BORDER 7 210 STOP 300 LET i=(5*RND+1): LET p-INT (S*RND)+1 310 IF i=p THEN GO TO 10 320 PAPER p: INK i 330 RETURN 469 GRAPHICS New keywords: DRAW, CIRCLE, POINT The screen is 22 lines by 32 columns – i.e. 704 character cells for graphics use. Each character cell consists of 8 by 8 dots (called pixels). Thus the pixel co-ordinates go from (0,0) bottom left-hand corner to (255, 175) the top right-hand corner. Colour Graphics You can do graphics in colour but remember that the pixels in any one character cell can only be either of the two colours corresponding to the current ink and paper values for the character cell. For example, let’s attempt to draw three circles one black, one blue and one red: 10 INK 2: CIRCLE 40,40,30 (red circle) 20 INK 1: CIRCLE 60,60,40 (blue circle) 30 INK 0 : CIRCLE 50,50,40 (black circle) This example shows that colour graphics is possible but can only be handled with great care. It is important to be clear about character cells as opposed to pixels. For example, you can draw three circles one black, one blue and one red: 10 INK 2 : CIRCLE 70,70,70 (red circle) 20 INK 4: CIRCLE 70,70,50 (blue circle) 30 INK 0 : CIRCLE 70,70,30 (black circle) Graphics Commands PLOT X.Y — inks in the pixel at the point (X,Y) DRAW X1,Y1 -inks in the line from the point specified previously to 470 the point X1 pixels to the right and Y1 pixels up from it. For example: 10 PLOT 20,30 - plots point (20,30) 20 DRAW 50,60 — draws line from point (20,30) to the point (20 50,30 + 60), i.e. (70,90). DRAW Х2,Ү2,А- draws an arc of a circle from the previously spec- ified point to the point X2 pixels to the right and Y2 pixels up from it with an angle A radians (anticlockwise). For example: 10 PLOT 30,30 20 DRAW 60,60 30 DRAW 80,80, PI CIRCLE X,Y,A draws a circle centre (X,Y) and radius A POINT (X,Y) will give @ if pixel at (X,Y) is paper colour and 1 if ink. For example: 10 CIRCLE 40,40,30 - draws circle centre (40,40) and radius 30 20 PRINT POINT (40,40)- pixel paper - 0 30 PRINT POINT (70,70)- pixel ink - 1 The commands INVERSE and OVER may be used with the graphics commands. For example: PLOT INVERSE 1 wil put paper colour at pixel PLOT OVER 1 will change ink to paper at pixel There is no UNPLOT on the Spectrum. We must use INVERSE or OVER. PLOT OVER 1 or PLOT INVERSE 1 effectively unplot the pixel. DRAW OVER 1 may be used to rubout a line while preserving the original information; compare result of program 1 with that of program 2. 18 FOR п-1 IO 22 2@ PRINT за NEXT n ге PLOT @,@: DRAN 255,175 435 STOF оа PLOT @,@: BRAW INVERSE 1; 25 2,175 ла FOR n= =1 TO 22 за PLOT @,@: DRAW INVERSE i:25 5,125 Е š w Try this one-line program: 10 PLOT 65,27: DRAW OVER 1; 120,120,49*3*PI Try different values in place of 49. EXAMPLES 1 Use of PLOT and DRAW commands (straight lines) This program makes use of these statements to draw a histogram by drawing a series of rectangles. Lines 70 and 80 produce a rectangle as shown: - W x, yo 10 REM Histogram using DRAW 20 READ х0,у0: LET x=x@ 25 REM Coordinates of LHS 30 READ w,n 35 REM Width and number of uni ts 40 FOR j=1 TO n 50 READ h 60 REM Unit height 70 PLOT x,y0 80 DRAW м,0: DRAW @,h: DRAW -w ,9: DRAW 0,-П 90 LET x=x+w 100 NEXT 1 105 DATA 5,5,20,12 110 DATA 12,45,67,98,134,167,17 0,136,124,87,46,20 472 2 Use of DRAW command (arcs of circles) This program produces a pattern by drawing four sets of semicircles. The basic plotting line is illustrated by the diagram of the effect of line 40. This is repeated within a series of four loops. п. -бӨха а 10 LET a=0 20 FOR n=129 TO 254 STEP 3 30 LET а=а+1 40 PLOT n,0: DRAW -6*a,0,PI 50 NEXT n 60 LET b= 76 FOR n=129 TO 254 STEP 3 80 LET b=b+l 90 PLOT n,175: DRAW -6*b,@,-PI 100 NEXT n 110 LET c=0 120 FOR п-90 ТО 174 STEP 3 130 LET с=с+1 140 PLOT 0,п: DRAW 0,-5%с,-РІ 150 NEXT n 160 LET d=0 176 FOR n=90 TO 174 STEP 3 180 LET d=d+l 190 PLOT 255,n: DRAW @,-6*d,PI 200 NEXT n und VN Akaros tirga 25840471515, қосулы Ту = УЫ, “4 a. ы % 4 ЖАЗАСЫ NN М У NN Г] тҮ a -—"" T МУМ z == N m LS m mh 5 x ay 5 4 Ux 1 VANY š “ ? i % 52) 25 ENO ORE WOW Arita Aadi Eek ^ n Te «саг ШЕН t EPLET Pe ESL rigat Al . 45 patatie И * Не азга БИН I NW D BI quati, 27777 ji ИР 1 $A; 473 Try inserting the following lines to see the effect of colour (note graphics is pixel but colour is character cells). 5 INK 2 55 INK 5 105 INK 6 155 INK 3 Use of CIRCLE command This command draws a circle and by varying the position of the centre and the radius of the circle we can obtain an acceptable drawing of a cone: 5 REM Draw a cone 10 READ i,p,b 15 REM ink,paper,border 20 READ cr 25 REM radius of cone 30 CLS : INK i: BORDER b: PAPE Кр: CLS 40 LET x-50 50 FOR r=cr TO 1 STEP -1 60 CIRCLE х,90,г 70 LET x=x+3 80 NEXT r 90 DATA 1,4,6 100 DATA 50,3 4 Use of user-defined functions for graph plotting The program below illustrates the use of the DEF FN and FN instructions in plotting graphs. Line 5 defines the function. Line 10 bypasses the subroutines (lines 20 to 100) and the main program first defines a=5 (line 120), then calls the first plot subroutine (lines 20 to 50), which uses a loop to define values of x. Line 30 makes the variable b equal to COS x and passes control to the subroutine at line 200 to evaluate y using the FN (y) instruction in line 200. Note this is a nested subroutine. Line 210 plots the results with suitable scale factors. On return to the subroutine the next value of x is taken and the process repeated. On return to the main program, the second subroutine, lines 70 to 100, is called, to plot the SIN x function by making b = SIN x. The variable a is redefined to equal 15 in line 150 on completion of the first two plots, and the subroutines are called 474 In sequence again. Note the capability to define a function using variables, and then define the values of the variables as appropriate. In this case, two values (COSx and SINx) are given to b, and the amplitude a is defined as first 5, then 15. Four plots are produced from the one user-defined function of line 5. > DEF ҒЫ чіхі-ьға 120 2 ее то 15 REM #xFUNCTION ONE PLOT жж ек *£*+SUBRGUT INE жж 20 FOR x=@ ТО 25 STEP .1 Зе LET b-COS x: GO SUB > SS REH xxEND FN ONE 3135 жж +++» X X <£ < kX x < ЖЖ 26 d Sa REM ##FUNCTION TUO PLOT zx = #X SUBROUTINE жж 1@5 НЕН xxEND FN THO Svs жж +++ ++ ++ X 2 3 x £ ЖЖЖ 110 БЕН #+#+++ ++ +++ kE x #5 5+ + + x= + жүнін PROGRAM жж 17@ GO SUB 7о 180 STOP 185 REM ##END MAIN PROGRAMS $ £ x 3 X X X X X X X x x 3 35 £ £ £ x = 19а REH ЖӘМШБВКБООТІМЕ-СЕН САТЕ + ж FUSING FN AND PLOT ex 200 LET u=FN u (x; 210 PLOT x2#1@,yYs#3+56 азге RETURN 230 REM rxzENDSUB FUNCTION USE#+ SREFES TEESE ЕЕЕ ЕЕ ET EF FFE SOUND New keyword: BEEP BEEP 6, 2 produces a note of duration 6 seconds and a pitch 2 semitones above middle C. The sound is fairly quiet; however fractional changes in pitch are available and it is possible to tune it to different instruments. To obtain the even-tempered scale of C major: BEEP 1,0 : BEEP 1,2: BEEP 1,4 : BEEP 1,5: BEEP 1,7: BEEP 1,9 : BEEP 1,11 : BEEP 1,12 475 The short program below gives some idea of the useful musical range and how it may be used for sound effects. 5 REM MusicaLl ranae 30 RERD pPil,Pzz 15 REM lowest and highest freq го FOR п=рӣ TO pz =e BEEP ,5,п ар PRINT AT (i13-n»;353,inei-21 со NEXT n 55 DATA -25,308 Ба PAUSE 200: CLS 70 REM $0 — effect ва LET х-.1 E aa FOR N-60 TO 20 STER 73. SS PRINT AT i380-n.23?.22. 100 BEEP .@5,n 130 LET x=x = De NEXT n ie іза BEEP .05,-25: EEEF .1,50 476 APPENDIX I ZX81 BASIC Summary CONVENTIONS nor m or p numeric expression string expression expression (string or numeric) variable name statement indicates an optional item indicates a string instruction Numeric variables are first character a ietter, then any alphanumeric characters. String variables are À to Z, followed by $. OPERATING COMMANDS LOADs SAVE s RUN [n] CLEAR NEW STOP CONT FAST SLOW INPUT/OUTPUT INSTRUCTIONS INPUT V INKEY$ LIST [n] PRINT [ell,e][;e][AT n,m;][TABn;] CLS PLOT m,n UNPLOT m,n LLIST [n] LPRINT [el]L,elL;e]l TAB n;] COPY OTHER INSTRUCTIONS POKE n,m PEEK n PAUSE n REM LET V[$] =e Load a program from tape. String may be null (‘*’’) (Loads first program) Save a program on tape Run program [starting at line n] Resets all variables in program Clears out program and variables Stops program execution Starts execution after BREAK or STOP Screen not displayed until end, PAUSE, INPUT, SLOW. Computes only. Screen displayed continuously, whilst computing Input numeric or string variable from keyboard Reads current input character. Does not wait for key to be pressed. Displays program [starting from line n] Print on screen Clears the screen Plot % graphic char. | 0< = m< = 63 horizontal Unplot pixel 0< = n< = 43 vertical List program on printer [starting from line n] Print on line printer Print a copy of screen on printer Store the value m in memory location n. O< = m< = 255. Returns the value stored in memory location n Halts program for п/50ѕесопаѕ (п/60 in U.S.). If n>32767 then pauses until key pressed. (n<65535) REMARK - comments. Ignored in program execution. Assigns the value of e to V 477 DIM У[$] (n[,m]) RAND [n] RND GOTO n GOSUB п RETURN IF e THEN FOR V =n TO m [STEP p] [] NEXT V TRIG FUNCTIONS SIN n COS п TAN n ASN n ACS n ATN n NUMERIC FUNCTIONS EXP n LN n SOR n INT n ABS n SGN n PI (m) STRING FUNCTIONS LEN s CHR$ n CODE s STR$ n VAL s + EXPRESSIONS PRIORITY 12 () 11 any function 10 жж 9 -в 8 ж ?4 6 +- 5 -,<>,<,>,<«,>- Dimensions array n by m (numeric), n strings of length m if string Random number seed Function returns a random number n. f = n<1 Transfers control to line n Go to Subroutine at line n Return from subroutine to line after last GOSUB If e is true THEN statement s is done, if e is false then s is not done. For e see expressions. Evaluates as TRUE = 1, FALSE = 0 V is any single letter control variable. m,n,p any numeric expressions. STEP 1 is assumed if STEP not specified Increments V by STEP. Goes to next line if V>m (m2n) or V&m (n2m). Sine n Cosine n Tangent n Arc Sine n (ARCSIN on keyboard) Arc Cosine n (ARCCOS on keyboard) Arc Tangent n (ARCTAN on keyboard) n evaluated as radians Exponent n or е" Log. nor ln n Square root of n Integer of n (rounds down) Absolute value of n 1 if n is positive, 0 if zero, — 1 if negative 3.1415927 Length of string s Character of code n (single character string) Code of first character in string s Convert numeric expression to String Convert string to numeric expression String concatenation bracketed expressions functions exponentiation unary minus multiplication division addition & subtraction equality & inequality 478 4 NOT 3 AND 2 OR ZX Spectrum Basic Summary CONVENTIONS n, m or p 5 е V [ ] logical inversion logical AND logical OR numeric expressions string expression expression (string or numeric) variable name statement indicates an optional item Numeric variables are first character a letter then any alphanumeric characters. String variables are a letter followed by $. OPERATING COMMANDS BREAK CLEAR CLEAR n CONT DELETE EDIT ENTER GRAPHICS LOAD s LOAD s CODE n,m LOAD s DATA V() MERGE s NEW RUN [n] SAVE s SAVE s LINE n SAVE s CODE n,m SAVE s SCREEN $ SAVE s DATA V() STOP VERIFY s VERIFY s CODE n,m VERIFY s DATA V() OTHER INSTRUCTIONS BIN n DATA el, ЖЗ, DEF FN interrupts operation e.g. execution, printer clears variables changes position of RAMTOP continues execution after BREAK or STOP allows deletion of character allows editing of current line line entered into program puts into graphics mode clears program and existing variables and loads program specified from tape. (string may be ‘‘”’ in which case the first program is loaded) loads m bytes into memory starting at address n loads specified array (string or numeric) into memory merges program s with the one already in memory clears program and variables runs program [starting at line n] Saves program and variables on tape saves program so that a LOAD is automatically followed by a GOTO n saves m bytes starting at address n saves the picture on tape saved specified array (string or numeric) on tape stops program execution verifies that program specified has been saved on tape verifies bytes specified have been saved on tape verifies array specified has been saved on tape puts binary number n into decimal separates multiple statements on a line gives data items within a program user-defined function definition. It must be 479 FN DIM V[$](n[,m]) FOR V =n TO m [STEP p] NEXT V GOSUB n RETURN GOTO n IF e THEN IN n OUT n,m LET VI$] = е[$] PAUSE n PEEK n POKE n,m READ У1[$], V2I$], ... USR n GRAPHICS followed by the name (single letter) of the string or numeric function and the definition - e.g. FNa(x,y,z)=xP3+y$44+z45 calls up the user-defined function. Arguments enclosed in brackets — e.g. FNa(3,5,7) dimensions array V. Numeric arrays of n rows [and m columns]. String array of n strings each of length m characters. Multi-dimension arrays possible V a single letter, initiates a loop V a single letter, completes loop go to subroutine at line n returns from subroutine to main program transfers control to line n executes statement when the condition is met. (There may be several numeric and logical conditions) returns the byte read from I/O port n writes value m to I/O port n assigns value e to variable V makes program wait a specified time (n = 0 waits for ever, n=1 to 65535 waits n/5@ seconds in UK and п/60 seconds in US) returns the value stored in the memory location n stores value m in memory location n allocates variables the values specified in DATA statements. calls the machine-code routine starting address n 22 lines with 32 columns available. Each character cell consists of 8 by 8 pixels. 256 horizontal points and 176 vertical points. CIRCLE n,m,p DRAW n,ml,pl PLOT n,m POINT (n,m) COLOURS: - black — blue — red - magenta green — cyan — yellow — white - O: сл > Ó rO в | draws а circle centre (n,m) and radius р draws line [arc] from previous specified point to a point relative n horizontal and m vertical [turning through angle p radians (anticlockwise if p positive)] Plots a pixel @< = n< = 255 horizontal 0< = m< = 175 vertical returns 0 (paper colour) or 1 (ink colour) of the pixel (n,m) 480 Picture is divided into 768 (24 lines of 32 columns) character cells. ATTR (n,m) BORDER n BRIGHT n FLASH n INK n INVERSE n OVER n PAPER n SOUND BEEP n,m INPUT/OUTPUT INSTRUCTIONS CLS COPY INKEY$ INPUT VI$] INPUT LINE V$ LIST [n] LLIST [n] LPRINT [е][,е][;е]ГТАВ n] PRINT [elL,el[;elLATp,ml][ TAB m] TRIG FUNCTIONS ACS n ASN n ATN n COS n SIN n TAN n (n evaluated in radians) NUMERIC FUNCTIONS ABS n EXP n INT n gives colour attributes of the character cell (n, m) @< = n< = 23 lines 0< = m< = 31 columns makes border specified colour (n = 0 to 7) controls brightness (n = 0 normal, п = 1 bright, n = 8 transparent) controls flashing (n = 0 normal, п = 1 flash, п = 8 no change) makes ink (foreground) specified colour (n = 0 to 7, n=8 transparent, n = 9 contrast) controls dot pattern (п= 0 normal, n=1 inverse) controls overprinting (п= 0 normal, n=1 mixing) makes paper (background) specified colour (n = to 7, n = 8 transparent, n = 9 contrast) produces sound of duration n seconds and pitch m semitones above (or below) Middle C. clears the screen prints out copy of screen on the printer reads current input character. Does not wait for key to be pressed. input numeric [or string] variable from keyboard allows string variable to be input without quotes displays program [starting from line n] lists program on printer [starting from line n] prints out on line printer prints on screen 22 lines @© = p< = 21 32 columns 0< = т< = 31 Arc cosine п Arc sine n Arc tangent n Cosine n Sine n Tangent n absolute value of n exponential n (i.e. e") integer of n (rounds down) 481 LN ñ PI RAND [n] RND SGN n SOR n STRING FUNCTIONS CHR$ п CODE s LEN s STR$ n VAL s VALS s natural logarithm of n (i.e. log n or In n) n, 3.1415927 random number seed function returns a random number between 0 and 1 returns 1 if n is positive, 0 if zero, — 1 if negative square root of n character of code n code of first character of string s returns length of string s converts numeric expression into string converts string expression into numeric converts s to a string expression (strips off quotes) PRIORITY see table for ZX81. 482 APPENDIX II ZX81 Error Codes Code Meaning 0 Successful completion, or jump to line number bigger than any existing. A report with code @ does not change the line number used by CONT. The control variable does not exist (has not been set up by a FOR statement) but there is an ordinary variable with the same name. An undefined variable has been used. For a simple variable this will happen if the variable is used before it has been assigned to in a LET statement. For a subscripted array variable it will happen if the variable is used before it has been dimensioned in a DIM statement. For a control variable this will happen if the variable is used before it has been set up as a control variable in a FOR statement, when there is no ordinary simple variable with the same name. For a numeric INPUT, will occur if non-numeric input received. Subscript out of range. If the subscript is negative, or bigger than 65535 then error B will result. Not enough room in memory. Note that the line number in the report (after the /) may be incomplete on the screen, because of the shortage of memory: for instance, 4/20 may appear as 4/2. No more room on the screen. CONT will make room by clearing the screen. Arithmetic overflow: calculations have led to a number greater than about 10, No corresponding GOSUB for a RETURN statement. You have attempted INPUT as a command (not allowed). STOP statement executed. CONT will not try to re-execute the STOP statement, but continues from next line. Invalid argument to certain functions. Integer out of range. When an integer is required, the floating point argument is rounded to the nearest integer. If this is outside a suitable range then error B results. 483 Situations Any NEXT Jumping into a loop. Any Subscripted variables (Lists and arrays) Substrings LET, INPUT, DIM, PRINT, LIST, PLOT, UNPLOT, FOR, GOSUB. Sometimes during function evaluation. PRINT, LIST. Any arithmetic. Division by zero is common cause. RETURN. No STOP statement before subroutine is common cause. INPUT STOP SOR, LN, ASN, ACS, VAL RUN, RAND, POKE, DIM, GOTO, GOSUB, LIST, LLIST, PAUSE, PLOT, UNPLOT, CHR$, PEEK, USR С The text of the (string) argument of VAL does not VAL form a valid numerical expression. D (i Program interrupted by BREAK. At the end of any statement as the program runs or in LOAD, SAVE, LPRINT, LLIST or COPY. (ii) The INPUT line starts with STOP. INPUT F . The program name provided is the empty string. SAVE Spectrum Error Codes The report has a code number or letter (so that you can refer to the following table), a brief message explaining what happened and the line number and statement number within that line where it stopped. (A command is shown as line 0. Within a line, statement 1 is at the beginning, statement 2 comes after the first colon or THEN, and so on.) The behaviour of CONTINUE depends very much on the reports. Normally, CONTINUE goes to the line and statement specified in the last report, but there are exceptions with reports 0, 9 and D. Here is a table showing all the reports. It also tells you in what circumstances the report can occur. Code Meaning 0 ОК Successful completion, ог jump ќо а line number bigger than any existing. This report does not change the line and statement jumped to by CONTINUE. NEXT without FOR The control variable does not exist (it has not been set up by a FOR statement), but there is an ordinary variable with the same name. Variable not found For a simple variable this will happen if the variable is used before it has been assigned to in a LET, READ or INPUT statement, loaded from tape or set up in a FOR statement. For а subscripted variable it will happen if the variable is used before it has been dimensioned in a DIM statement or loaded from tape. Subscript wrong A subscript 1s beyond the dimension of the array, or there are the wrong number of subscripts. If the subscript is negative or bigger than 65535, then error B will result. Out of memory There is not enough room in the computer for what you are trying to do. If the computer really seems to be stuck in this state, you may have to clear out the command line using DELETE and then delete a program line or two (with the intention of putting them back afterwards) to give yourself room to manoeuvre with — say - CLEAR. 484 Situations Any NEXT Jumping into a loop is a common cause. Any Subscripted variables (arrays), Substrings LET, INPUT, FOR, DIM, GO SUB, LOAD, MERGE. Sometimes during expression evaluation. Code Meaning 5 Out of screen An INPUT statement has tried to generate more than 23 lines in the lower half of the screen. Also occurs with PRINT AT 22,... Number too big Calculations have led to a number greater than about 1055. RETURN without GO SUB There has been one more RETURN than there were GO SUB. End of file STOP statement After this, CONTINUE will not repeat the STOP, but carries on with the statement after, or next line after, STOP. Invalid argument The argument for a function is no good for some reason. Integer out of range When an integer is required, the floating point argument is rounded to the nearest integer. If this is outside a suitable range then error B results. Nonsense in BASIC The text of the (string) argument does not form a valid expression. BREAK - CONT repeats BREAK was pressed during some peripheral operation. The behaviour of CONTINUE after this report is normal in that it repeats the statement. Compare with report L. Out of DATA You have tried to READ past the end of the DATA list. Invalid file name SAVE with name empty or longer than 10 characters. No room for line There is not enough room left in memory to accommodate the new program line. STOP in INPUT Some INPUT data started with STOP, or- for INPUT LINE - BREAK was pressed. Unlike the case with report 9, after report H CONTINUE will behave normally, by repeating the INPUT statement. FOR without NEXT There was a FOR loop to be executed no times (e.g. FOR n=1 TO 0) and the corresponding NEXT statement could not be found. 485 Situations INPUT, PRINT AT Any arithmetic. Division by zero is common cause. RETURN. No STOP statement before a subroutine is common. Microdrive, etc, operations only. STOP SOR, LN, ASN, ACS, USR (with string argument) RUN, RANDOMIZE, POKE, DIM, GO TO, GO SUB, LIST, LLIST, PAUSE, PLOT, CHR$, PEEK, USR (with numeric argument) VAL, VAL$ LOAD, SAVE, VERIFY, MERGE, LPRINT, LLIST, COPY. Also when the computer asks scroll? and you type READ SAVE Entering a line into the program INPUT FOR Code Meaning J K Invalid I/O device Invalid colour The number specified is not an appropriate value. BREAK into program BREAK pressed, this is detected between two statements. The line and statement number in the report refer to the statement before BREAK was pressed, but CONTINUE goes to the statement after (allowing for any Jumps to be done), so it does not repeat any statements. RAMTOP no good The number specified for RAM TOP. is either too big or too small. Statement lost Jump to a statement that no longer exists. Invalid stream FN without DEF User-defined function Parameter error Wrong number of arguments, or one of them is the wrong type (string instead of number or vice versa). Tape loading error A file on tape was found but for some reason could not be read in, or would not verify. 486 Situations Microdrive, etc., operations only INK, PAPER, BORDER, FLASH, BRIGHT, INVERSE, OVER; also after one of the corresponding control characters Any CLEAR; possibly in RUN RETURN, NEXT, CONTINUE Microdrive, etc, operations only FN FN VERIFY, LOAD or MERGE APPENDIX III ZX81 Character Codes by Keyboard Arrangement Note: Character codes for both the ZX81 and the Spectrum are listed in order of code number in Section P, and an alphabetic list for the Spectrum is included in Unit W-1. 1. KEYBORD CHARACTERS CHARACTER CODE CHARACTER CODE PLOT 246 NEW 230 UNPLOT 252 SAVE 248 REM 234 DIM 233 RUN 247 FOR 235 LINE2 RAND 249 LINES GOTO 236 RETURN 254 GOSUB 237 IF 250 LOAD 239 INPUT 238 LIST 240 POKE 244 LET 241 PRINT 245 COPY 255 CLEAR 253 CONT 232 CLS 251 LINE4 SCROLL 231 NEXT 243 PAUSE 242 BREAK — TOTAL 26 Characters. May be entered when mode cursor appears. Obtained by pressing desired key. 2. SHIFT CHARACTERS CHARACTER CODE CHARACTER CODE EDIT 117 ж 5 192 AND 218 OR 217 THEN 299 STEP 224 TO 223 <= 219 LINE1 «€ 114 LINE2 <> 221 113 >= 220 À 112 $ 13 > 115 ( 16 GRAPHICS 116 ) 17 RUBOUT 119 es 11 487 CHARACTER CODE CHARACTER CODE STOP 227 : 14 LPRINT 223 қ 25 SLOW 228 ? 15 FAST 229 / 24 LINE: 3 LLIST 226 LINE4 * 23 “. 216 < 19 - 22 > 18 + 21 i 26 = 20 £ 12 FUNCTION 121 TOTAL 39 Characters. Obtained by pressing and keys together. 3. LETTER CHARACTERS CHARACTER CODE CHARACTER CODE 1 29 А 38 2 30 S 56 3 31 D 41 4 32 F 43 LINE 1 5 33 LINE3 G 44 6 34 H 45 7 35 J 47 8 36 K 48 9 37 L 49 0 28 NEWLINE 118 (ENTER) о 54 SHIFT W 60 Z 63 F 49 K 61 R 55 C 40 LINE? Т 57 LINE4 V 59 Y 62 B 39 U 58 N 51 I 46 M 50 O 52 27 Р 53 SPACE 0 TOTAL 39 Characters. May be entered when mode cursor appears. Obtained by pressing the desired key. 488 4. GRAPHICS CHARACTERS CHARACTER CODE CHARACTER CODE F| 1 ЕЕ 8 [4 2 FS 10 Lal 135 ы 9 а) 4 ЫШ 138 ІЛМЕ 1 u 5 LINE 3 E 137 ыш 131 ES 136 = 3 inverse — 150 . 133 inverse + 149 Inverse = 148 ma 129 inverse : 142 М 130 Inverse ; 153 F 7 Inverse ? 143 LINE 2 = 132 LINE 4 inverse / 152 = 6 Inverse * 151 Fg 134 inverse < 147 inverse $ 141 inverse > 146 Inverse ( 144 Inverse , 154 Inverse ) 145 Inverse £ 140 inverse "' 139 TOTAL 36 Characters. Entered in mode, obtained by pressing |SHIFT| |GRAPHICS | keys. Character obtained by pressing [SHIFT] [CHARACTER 5. INVERSE GRAPHICS CHARACTERS INVERSE INVERSE CHARACTER ` CODE CHARACTER CODE 1 157 Q 182 2 158 W 188 3 159 E 170 4 160 R 183 LINE 1 5 161 LINE2 Т 185 6 162 Y 190 7 163 U 186 8 164 I 174 9 165 О 180 0 156 P 181 489 INVERSE INVERSE CHARACTER CODE CHARACTER ` CODE A 166 Z 191 S 184 x 189 D 169 C 168 F 171 V 187 LINE3 G 172 LINE4 B 167 H 173 N 179 J 175 M 178 K 176 | 155 i, 177 128 (SPACE) TOTAL 38 Characters. May be entered in mode obtained by keys. Obtained by pressing desired keys. 6. FUNCTION CHARACTERS CHARACTER CODE CHARACTER CODE SIN 199 LN 205 COS 200 EXP 206 TAN 201 AT 193 INT 207 INKEY$ 65 LINE2 AND 64 LINE4 NOT 215 STR$ 213 n(PI) 66 CHR$ 214 CODE 196 PEEK 211 TAB 194 ARCSIN 202 ARCCOS 203 ARCTAN 204 LINE 3 SGN 209 ABS 210 SOR 208 VAL 197 LEN 198 USR 212 TOTAL 25 Characters. Мау be entered іп [Е] mode obtained by pressing [ SHIFT | key. Characters obtained by pressing desired character key. The mode operates for only one character input. 490 APPENDIX IV Use of Cassette Tapes The following information concerns the use of cassette tapes for program storage and retrieval. Other details of personal tape library practice can be found in the main text. 1 New tapes: Always ‘fast forward’ and ‘rewind’ a tape completely before use for program storage. This ensures an even winding and tension. If you have the patience, running the tape one way in ‘play’ mode after fast forward and reverse is desirable. Do not use the first 15 or 20 seconds of any tape. Most tape problems of coating loss and stretch occur in this portion of the tape. Always rewind tapes fully after use, so as to not leave tape with program data exposed. Never touch the surface of the tape. Before inserting a tape in the cassette player, take up the slack in the tape (using a finger or a pencil) by turning one drive wheel until the other moves. Always replace tapes in the correct library boxes immediately after use. Leave the label side (if only one label) showing. Tapes with programs meant to be permanent should have the tags removed to prevent accidental erasure. The holes can always be covered with sticky tape if you decide in the future to record over a program. Clean the tape-recorder heads after 2 or 3 hours’ running time with a head cleaner cassette or head cleaner fluid. De-magnetise heads every 10 or 12 hours’ running. Leave long gaps (at least 20 seconds) between programs, if more than one program is on a tape. Note the tape counter readings for beginning and end of each program. Remember that the tape counter is not highly accurate. You can use the TV screen to find a gap between programs, watching for the thick black lines of a program load display change to the thin diagonal lines of a ‘blank tape’ display. Loading problems. These are notes for the ZX81 user. No problems should be encountered with the Spectrum in this respect. For each individual ZX81/cassette system, no problems should be encountered with SAVEing and LOADing programs with the TONE control set high, and the VOLUME at 3/4 volume. The characteristics of tape recorders vary somewhat, however, and problems may be encountered in LOADing programs which have been SAVEd on a different recorder. Here is a sequence to be followed if a program proves difficult to LOAD. A Set the TONE control for maximum treble (‘High’). B Set the VOLUME to about three-quarters of the maximum. С Rewind tape to the beginning. D Type: LOAD “A” - i.e. any letter/word except the program name. Press PLAY on the cassette, then NEWLINE (ENTER) on the 7Х81. When the thin, slightly sloping black lines change to the programs' typical thick black and white lines, with approximately equal black and white bands, with the white crossed by vertical black lines: (a DECREASE THE VOLUME until this changes back to the THIN lines. (b Now INCREASE THE VOLUME, noting where the THICK black and white program lines eventually seem to become more unsettled or predominantly black. Also if you listen to the recording you may be able to notice when the volume is too high and causes distortion. E Setthe VOLUME midway between these two points (a) and (b). Rewind tape. Type: LOAD “(Тһе program name)”. Press PLAY on the cassette, then NEWLINE (ENTER) on the ZX81. If the screen suddenly clears before the program should end, this may mean volume is still too low. 491 The ZX81 may need to be re-set by pulling out the d.c. supply plug and re-inserting it if the cursor does not return to the screen, either by itself or when BREAK is used. LOAD again, slightly increasing the volume, after rewinding the tape. If you cannot get a definite, THICK black and white line pattern even at full volume then your recorder may not be powerful enough to load from the signal strength on this specific tape. Test this by using another recorder, or recorder/ZX system. Once the program has LOADed, SAVE it on to a tape in your own recorder. Turn off cassette recorder and take the EAR/MIC leads out of the ZX81 before swapping recorders, or else you may cause the system to crash whilst taking out and re-inserting the plugs. 9 NEVER place a tape on top of the TV monitor. This can affect the signals stored on the tape because of the electromagnetic field generated by the TV. 492 APPENDIX V System Variables — ZX81 Notes: X The system may crash if the variable is poked. N Poking the variable will have no lasting effect. S The variable is saved by SAVE. The number in column 1 is the number of bytes storing the variable. For two bytes, the first one is the less significant byte. To poke a value M to a two-byte variable at address N use: To peek its value, use the expression Notes X1 X2 N1 N2 Address 16384 16385 16386 16388 16390 16391 16393 16394 16396 16398 16400 16402 16404 16406 POKE N (M - 256*INT(M/256)) POKE N + 1, INT M/256 PEEK N + 256*PEEK(N + 1) Name ERR_NR FLAGS ERR_ SP RAMTOP MODE PPC VERSN Е PPC D FILE DF CC VARS DEST E LINE CH ADD Contents 1 less than the report code. Starts off at 255 (for — 1), so PEEK 16384, if it works at all, gives 255. POKE 16384, N can be used to force an error halt: N < = 14 gives one of the usual reports, 15 <=N<=34 or 99 < = N<127 gives an non-standard report, and 35 < = N < = 98 may disrupt the display file. Various flags to control the BASIC system. Address of first item on machine stack (after GOSUB returns). Address of first byte above BASIC system area. You can poke this to make NEW reserve space above that area or to fool CLS into setting up a minimal display file. Poking RAMTOP has no effect until one of these two is executed. Specified K, L, F or G cursor. Line number of statement currently being executed. Poking this has no lasting effect except in the last line of the program. Q Identifies ZX81 BASIC in saved programs. Number of current line (with program cursor). See Unit O4. Address of PRINT position in display file. Can be poked so that PRINT output is sent elsewhere. See Unit U2. Address of variable in assignment. See Unit U2. Address of the next character to be interpreted: the character after the argument of PEEK, or the NEWLINE (ENTER) at the end of a POKE statement. 493 16408 16410 16412 16414 16415 16417 16418 16419 16421 16423 16424 16425 16427 16429 16430 16432 16434 16436 16438 16439 16440 16441 16442 16443 16444 16477 16507 X PTR STKBOT STKEND BERG MEM not used DF SZ 5 TOP LAST K MARGIN NXTLIN OLDPPC FLAGX SIRLEN T ADDR SEED FRAMES COORDS PR CC S POSN CDFLAG PRBUFF MEMBOT not used Address of the character preceding the § marker. See Unit U2. Calculator's b register. Address of area used for calculator's memory. (Usually MEMBOT, but not always.) The number of lines (including one blank line) in the lower part of the screen. See Unit Q4. The number of the top program line in automatic listings. Shows which keys pressed. Debounce status of keyboard. Number of blank lines above or below picture: 55 in Britain, 31 in America. Address of next program line to be executed. Line number to which CONT jumps. Various flags. Length of string type assignment. Address of next item in syntax table (very unlikely to be useful). The seed for RND. This is the variable that is set by RAND. Counts the frames displayed on the television. Bit 15 is 1. Bits @ to 14 are decremented for each frame sent to the television. This can be used for timing, but PAUSE also uses it. PAUSE resets to 0 bit 15, and puts in bits @ to 14 the length of the pause. When these have been counted down to zero, the pause stops. If the pause stops because of a key depression, bit 15 is set to 1 again. x-coordinate of last point PLOTted. y-coordinate of last point PLOTted. Less significant byte of address of next position for LPRINT to print at (in PRBUFF). Column number for PRINT position. Line number for PRINT position. Various flags. Bit 7 is on (1) during compute and display mode. Printer buffer NEWLINE). Calculator memory area; used to store numbers that cannot conveniently be put on the calculator stack. destination in (33rd character is 494 System Variables — Spectrum Notes: X The system may crash if the variable is poked. N Poking the variable will have no lasting effect. The number in column 1 is the number of bytes in the variable. For two bytes, the first one is the less significant byte. To poke a value M to a two-byte variable at address N use and to peek its value, use the expression Address 23552 23560 23561 23562 23563 23565 23566 23568 23606 23608 23609 23610 23611 23612 23613 23615 23617 23618 23620 23621 POKE N(M - 256% INT(M/256)) POKE N + 1, INT M/256 POKE N + 256* PEEK (N + 1) Name KSTATE LAST K REPDEL REPPER DEFADD K DATA TVDATA STRMS CHARS RASP PIP ERR NR FLAGS TV FLAG ERR SP LIST SP MODE NEWPPC NSPPC PCC Contents Used in reading the keyboard. Stores newly pressed key. Time (іп 50ths of a second - in 60ths of a second in N. America) that a key must be held down before it repeats. This starts off at 35, but you can POKE in other values. Delay (in 50ths of а second - in 60ths of a second in America) between successive repeats of a key held down: initially 5. Address of arguments of user-defined function if one is being evaluated; otherwise 0. Stores 2па byte of colour controls entered from keyboard. Stores bytes of colour, AT and TAB controls going to television. Addresses of channels attached to streams. 256 less than address of character set (which starts with space and carries on to the copyright symbol). Normally in ROM, but you can set up your own in RAM and make CHARS point to it. Length of warning buzz. Length of keyboard click. 1 less than the report code. Starts off at 255 (for - 1) so PEEK 23610 gives 255. Various flags to control the BASIC system. Flags associated with the television. Address of item on machine stack to be used as error return. Address of return address from automatic listing. Specifies K, L, C, E or G cursor. Line to be jumped to. Statement number in line to be jumped to. Poking first NEWPPC and then NSPPC forces a jump to a specified statement in a line. Line number of statement currently being executed. 495 Notes N2 N2 кі ка к ка М) Address 23623 23624 23625 23627 23629 23631 23633 23635 23637 23639 23641 23643 23645 23647 23649 23651 23653 23655 23656 23658 23659 23660 23662 23664 23665 23666 23668 23670 23672 23675 23677 23678 23679 23680 Name SUBPPC BORDCR E PPC VARS DEST CHANS CURCHL PROG NXTLIN DATADD E LINE K CUR CH ADD X PTR WORKSP STKBOT STKEND BREG MEM FLAGS2 DF SZ S TOP OLDPPC OSPCC FLAGX STRLEN T ADDR SEED FRAMES UDG COORDS P POSN PR CC Contents Number within line of statement being executed. Border colour * 8; also contains the attributes normally used for the lower half of the screen. Number of current line (with program cursor). Address of variables. Address of variable in assignment. Address of channel data. Address of information currently being used for input and output. Address of BASIC program. Address of next line of program. Address of terminator of last DATA item. Address of command being typed in. Address of cursor. Address of the next character to be interpreted: the character after the argument of PEEK, or the NEWLINE (ENTER) at the end of a POKE statement. Address of the character after the Syntax error marker. Address of temporary work space. Address of bottom of calculator stack. Address of start of spare space. Calculator's b register. Address of area used for calculator's memory. (Usually MEMBOT, but not always.) More flags. The number of lines (including one blank line) in the lower part of the screen. The number of the top program line in automatic listings. Line number to which CONTINUE jumps. Number within line of statement to which CONTINUE jumps. Various flags. Length of assignment. Address of next item in syntax table (very unlikely to be useful). The seed for RND. This is the variable that is set by RANDOMIZE. 3 byte (least significant first), frame counter. Incremented every 1/50th second (U.K.) or 1/60th second (U.S.). Address of 1st user-defined graphic. x-coordinate of last point plotted. y-coordinate of last point plotted. 33-column number of printer position. Less significant byte of address of next position for LPRINT to print at (in printer buffer). string type destination in 496 Notes Address 23681 23682 23684 23686 23688 23689 23690 23692 23695 23694 23695 23696 23697 23698 23728 23730 23732 Name ECHO E DF CC DFCCL S POSN SPOSNL SCR CT ATTR P MASK P ATTR T MASK T P FLAG MEMBOT RAMTOP P-RAMT Contents Not used. 33-column number and 24-line number (in lower half) of end of input buffer. Address in display file of PRINT position. Like DF CC for lower part of screen. 33-column number for PRINT position. 24-line number for PRINT position. Like S POSN for lower part. Counts scrolls: it is always 1 more than the number of scrolls that will be done before stopping with scroll? Permanent current colours, etc. (as set up by colour statements). Used for transparent colours, etc. Any bit that is 1 shows that the corresponding attribute bit is taken not from АТ ТК P, but from what is already on the screen. Temporary current colours, etc (as set up by colour items). Like MASK P, but temporary. More flags. Calculator's memory area; used to store numbers that cannot conveniently be put on the calculator stack. Not used. Address of last byte of BASIC system area. Address of last byte of physical RAM. 497 | a en a E Е Bd inte Е. BL SANE - ion wt Е | т ys - y rw б» А e ° я Е * - TIN» Ë "ae © ee et j* E. g “Hee oa’ 7 90° та) * gs s тыр “ma = 41 те vv v vas? dt 27» a Е e" s». o mE eL = “ ауа B Be “,.”.- *(* T i Tor D ““ “us т game ч © c Z Е "> 5 9 “p Н & a e 5 А Р Bn A LIS š - 2 g’ E f LU Е еу =, E UE Sis Ae F: og е. da ^g s ç =: % J ер с 2 * š 8 4 e APPENDIX VI PROGRAM LIBRARY This appendix contains applications and utility programs and routines, and games. Some of these have been referred to in the main text. Due to lack of space, the programs are not fully documented. 1. Polar Program produces a polar coordinate graph of the function entered as A$. This must be an expression using A as the dependent variable. Since a common cause of failure of the VAL function (giving the error code A) on the ZX81 is the exponentiation function, this is noted and a way of avoiding it given. The angle increment (in radians) is entered as DA. The appropriate scale factor can be experimented with. If you get a small cramped plot (or even a single pixel), increase the scale factor. If the plot goes off the screen, you are informed that the scale factor needs reducing (line 250). Polar coordinate plots can be thought of as an X,Y plot with the X axis bent into a circle, and the Y axis plot point defined as a distance R (radius) away from the centre point. Y is then positioned Бу the COS and SIN functions in lines 190 апа 200. Spectrum: For use on the Spectrum change ** to À in line 30, and delete line 160. Change line 70 to read 70 PAUSE 0. In lines 190 апа 200 the centre point must be set as plot co-ordinates 84, 82, with LET X=84+(R*COS A*SC) and LET Y = 82 + (R*SIN A * SC). Line 210 must have the limits of X and Y set at 255 and 176 respectively. Line 270 should read PAUSE 0. The program will then run, but you can also modify it to use the DEF FN and FN instructions: Define the function in line 50, with a DEF FN a() - SIN A * 3 or whatever the derived function is, and use LET R = FN a() in line 180. Change the instructions in line 40 to suit. ле REM “POLAR” Ба PRINT TAB 8; “4FOLAR ғістат; TAB а; жж аа ааа” Зе PRINT ,,"FLOT ROUTINE FOR б OLAR" , "COORGDINATES ENTER FUMCTI ON TO^,"BE PLOTTED WITHOUT USE О Б #4", "(RAISED ТО POWER! FLUMCIIO M.USE^,"SINsSINsSIN,NMOT SXMsa3,7 OR" “EXAMPLE.USE A FOR ANGLE.“ ,” YOU MUST ALSO ENTER SCALE “ , "FRc TGR ANG ANGLE INCREMENT.” - 42 PRINT ,, ENTER EMPRESATON 1 о BE PLOTTED” S@ INPUT AS ба PRINT “ENTER ANGLE IMCREMENM 7a INPUT РЯ aae PRINT “ENTER SCALE ҒОСҒОЭНЭС” а INPUT 5С imo СЫЗ 269 КЕМ ЖРБІМТ RAES RHE PLOT INFORMAT ION +s i120 FOR F=1 ТО 282 120 PRINT AT 11,Ғ,;”,%” 250 PRINT AT F,28;":”" 142 NEXT F icd PRINT AT @,32;R3;RT 32,393; “2 .F.2'"; SC; TAB 18; "RMGLE INC. =” ; еЗ 15а FAST 369 REM #ROUND THE CIRCLe, SYES iFa FOR я-а TO 2xPI STEP OR i179 REM #EVALUATE FUNCT IQI H ізе LET R-URL RS 139 REM sNEXT LINES GET J," CONVERTED TO POLAR СОБ RM SIM: COORDINATES, TIMES SCHLE ғостовк, AND SET WITH CENTRE AT 22 224 290 LET X-204iRxCOS Bs5cCi 200 LET Yz204 iR 351N nasci 210 IF x»60 OR XQ OR Yia OR у сә THEN сото 252 220 PLOT X,Y 499 =5@ NEXT R 24e сото 292 250 PRINT AT 19,2,’ "OUT оғ BLUT RANGE. REDUCE SCALE”, “ғастов,” =68 few NE ‘PRESS B KEY, THEM ЕВР 289 GOTO өе 290 REM #FINISH# +5. Set. =; a ANGLE INC., =, G= 2. Home Accounts Program allows household expenses for each day for a month to be entered under various headings, which may of course be changed to suit your needs. Income is entered, and credits may also be input under any heading. After entries have been made, a statement of account is derived, which may be printed out. A breakdown of account by heading can also be printed, and the program and data saved to tape so that future entries may be added. The data is stored in string arrays, and these could be increased up to the limits of memory if a longer period were to be catered for. The program is menu-driven, and all inputs allow the user to check for errors and re-enter if necessary. > REM "HOME ACCOUNTS" 10 REM *INITIALISATION* ZO LET TOTAL=0 ЗО LET I=1 40 LET C=0 50 LET Z$="END " 61 REM жАККАҮ DECLARATION* е2 DIM D$(3156) é3 DIM I$(31,1)2 65 DIM АСЗ1› ее DIM A$C10) 67 DIM (%(631) ев DIM К%(6315) &v GOSUB 170 70 REM *MAIN МЕМ 3 CLS 75 PRINT АТ 0%8: "HOME ACCOUNTS 77 PRINT АТ 1%8:"---- -------- 80 PRINT АТ 4:10: «MAIN MENU*" £1 PRINT AT 5%11:"---- ---- 500 82 РКІМТ AT 7»2: "А"; АТ 7,103" TO ADD AN ENTRY" ӨЗ PRINT АТ 9:2: "5"; FOR ACCOUNT STATEMENT" 84 PRINT АТ 112: "С"; ;"FOR CODE BREAKDOWN" 83 PRINT AT 13,2; "X"; ;"TO EXIT" AT 9310:" AT 11310 AT 13:10 86 PRINT АТ 15%8: "ОРТІОМ 2" 87 INFUT 0% 88 IF 0Ф-"А" THEN GOTO 310 8? IF ü$-"S" THEN GOTO 610 90 IF G$-"C" THEN GOTO 805 100 IF 0%-"Х" THEN STOP 120 PRINT АТ 1538: "UNKNOWN OPTI ON: "70$ 130 PAUSE 100 140 PRINT АТ 15:8;" 150 GOTO 95 160 КЕМ 170 LET 180 LET 190 LET 200 LET 210 LET 215 LET 220 LET 230 LET 240 LET жж жж ЖЖЕХРЕМБЕ CODE *#INITIALISAT ION C$cioz"o" K$(1)="GROCERY" C$C2)z"P" {$(2)="PETROL" C$(s9="C" K$(3)="CAR REPAIRS“ C$Cc45z"R" K$(4)="RA TES" С$%$(5)="М" 250 LET K$(S5)="MISCELLANEQUS" 260 LET C$cé)="I" 270 LET K$(6)="INCOME" 280 RETURN 300 REM #INFUTTING ПАТАж 310 CLS 320 PRINT AT 0:8; "НОМЕ ACCOUNTS 330 PRINT АТ 1:38; "---- -------- 350 PRINT АТ 5:57" T 360 PRINT AT 4,2; "ENTER DATE (E б. 25 NOV: OR PA VEND. ae FINISH)" 370 INFUT D$(1) 380 IF 0%(1)="" THEN GOTO 370 387 PRINT AT 4927" 386 390 392 )?"; 394 395 396 398 IF П%(12-7% THEN GOTO 570 РКІМТ AT 5,5; "DATE: ";D$(1) PRINT АТ 1035; “СОЕКЕСТ (Y/N INPUT Q$ IF @$="N" THEN GOTO 250 IF 0% <> "Y" THEN GOTO 394 PRINT AT 10.53" 399 PRINT AT 11557" 501 439 GOSUB 1000 PRINT АТ 16,5; "EXPENSE CODE INPUT I$CI) IF I$(I)z"" THEN GOTO 430 GOSUB 2000 » FOR J=1 TO é IF 1%(12-С%(.1) THEN GOTO 44 NEXT J PRINT AT 7:95; "UNKNOWN EXFEN SE CODE: ";I$CID 440 441 442 FAUSE 100 GOTO 410 РКІМТ АТ 739:"EXFENSE CODE: "PES CJ) 444 )?" 446 447 448 449 460 470 PRINT AT 11:5; "CORRECT (Y/N INPUT 0% PRINT AT 11953" IF @$="N" THEN GOTO 410 IF Q$ <> "Y" THEN GOTO 444 РКІМТ AT 13,53" PRINT AT 9,9; "AMOUNT (- FOR EXPENSE) 7" 480 483 487 490 500 22"; 510 220 530 932 534 536, эзе 540 550 560 970 INFUT A$ IF A$="" THEN GOTO 480 PRINT AT 9357" FRINT AT 9:5; "AMOUNT: “FAG PRINT AT 13,5; "CORRECT (Y/N INPLIT Q$ IF Q$="N" THEN GOTO 460 IF 0% 4» "Y" THEN GOTO 510 PRINT AT 12,5; " PRINT AT 9557" PRINT AT 7,55" LET ñ(I)= VAL A$ (ЕТ IsI-*1 LET C=C+1 GOTO 350 PRINT AT 10,3; "00 YOU WISH ТО SAVE THESE": AT 11,2; "ENTRIES (Y/N) 7" 575 380 INPUT 0% IF Q$="N" THEN GOTO 73 589 IF 06 <> "Y" THEN GOTO 575 590 PRINT АТ 10,2;"5ЕТ UP CASSE TTE RECORDER: WHEN READY PRESS A NY КЕҰ" 595 596 999 IF ІМКЕҮ% ="" THEN GOTO 595 SAVE “HOME ACCOUNTS" GOTO 73 600 REM *STATEMENT OF ACCOUNT 902 610 CLS 620 PRINT TAB 5: "ЗТАТЕМЕМТ OF A CCOUNT" 630 PRINT TAB 5%"-------- -- -- 640 PRINT 650 PRINT "DATE": TAB 8% "ТҮРЕ"? TAB 15: "СК"; TAB 25; "DB" 660 PRINT "eese" TAB Bi "е7 TAB i357 "-<-"3. TAB 257 "==" 670 FOR I=1 TOC 630 PRINT В%(10: TAB 2:1%С12; 690 IF А(12>0 THEN GOTO 720 700 PRINT TAB 25; ABS ACT) 710 GOTO 730 720 PRINT TAB 15;А(1) 730 LET TOTAL=TOTAL+ACI) 740 PRINT 750 NEXT I 793 PRINT TAB 2ОҒ”------ " 755 FRINT "BALANCE"; TAB 20; TOT 766 PRINT AT 2132: "COPY TO PRIN ТЕК СҮМ) 7" 767 INPUT Q$ 768 IF ü$-"N" THEN GOTO 73 769 IF 0% <> "Y" THEN GOTO 767 770 PRINT AT 21,23 "ЗЕТ UP PRINT ER AND FRESS A KEY" 773 IF INKEY$ ="" THEN GOTO 773 775 PRINT АТ 21927" 780 COFY 790 GOTO 73 S00 REM **BREAKDOUWN OF жж XACCOUNT BY CODE жж 905 CLS 810 PRINT “STATEMENT OF ACCOUNT 830 PRINT "CODE"; TAB 15% "TOTAL 840 PRINT 250 LET J=1 255 (ЕТ TOTAL=0 860 FOR Ісі TO C $70 IF I$(I)=C$(J) THEN LET TOT AL=TOTAL+A(T) 280 NEXT I 990 PRINT K$(J); TAE 15; TOTAL 900 LET J=J+1 910 IF J <= 6 THEN GOTO 855 926 PRINT АТ 2192: "COPY TO PRIN TER (Y/N? ?" 927 INPUT Q$ 928 IF ü$-"N" THEN GOTO 73 929 IF 0% <> "Y" THEN GOTO 927 эзо PRINT AT 21,23 "БЕТ UF PRINT ER AND FRESS A KEY" 940 IF INKEY$ ="" THEN GOTO 940 503 PIO FRINT AT Z1s27" veo COPY 990 GOTO 73 1000 REM 33433) )9 9 09 9 ! ) 9 09 X 9 * 99€ X*EXFENSE CODE МЕМІІжж *#*SUBROUT INE жж 3C EIE ЗЕ ЗЕ ЕЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЗЕ ЕЕ EHR 1020 PRINT АТ 7,5;"*ЕХРЕМ5Е CODE МЕМИ+ : 1090 PRINT AT бұз!” eee m ne 1050 PRINT AT 9*5;"G"; AT 2157" GROCERY " 1060 PRINT AT 10,93 "Е"; АТ 10,15 т КЕТКЕШ." 1070 PRINT АТ 11:5;"C"3 AT 115915 ;"CAR REPAIRS" 1080 PRINT AT 12,5; "Е"; AT 12,15 ; "RATES" 1090 PRINT AT 12:5;:"M": AT 13515 ; MISCELLANEOUS" 1100 PRINT AT 14,53 "1"; AT 14515 ; "INCOME" 1110 RETLIRN 2000 PRINT AT 16,5;" 2010 PRINT AT 14957" "; АТ 14515 2020 PRINT АТ 13,93" "; AT 13315 2050 PRINT АТ 12957" "; AT 12,15 = d y 2040 PRINT AT 11,5;" "Ó"; AT 11,15 ә 41 y 2050 PRINT AT 10957" "; AT 10,15 = и , 2060 PRINT AT 9,9:" "; AT 9?,15;" 2070 PRINT АТ 3.93" 2080 PRINT AT 7,93" 2090 RETURN 3. Resval Program derives the preferred resistor value (i.e. the closest standard resistance) from inputs of the voltage and current required in a circuit. From these inputs (in volts and amps) the actual resistance is calculatead by Ohms Law (R = V/I). This value, rounded to two significant figures, is then used to calculate the value L, 10 to the power L, being the multiplier for the resistor value. The values stored in the array X(13), entered as shown in the first program, are then compared with the calculated resistance. The first value stored in the array which gives a value greater than R is then used to print out the preferred value for the component. The current and power using a resistor of this value are then printed. The user may then choose to run the calculation again with different inputs until the best solution is achieved. This illustrates the basic principle of computer-aided design (CAD) of circuits, where the derived theoretical values are modified to suit the actual components available. 504 The array creation program and data values (of resistors with +10% tolerance) are given below. This program is then edited out, and RESVAL entered. Alternatives to storing the data in an array would be to assign each value of the array X with a LET statement, or, if using a Spectrum, to place the values in a DATA statement. Both these methods would eliminate the problem of avoiding the use of RUN. Spectrum: Change ** to ^ in lines 220, 240 апа 270. Change line 340 to read 340 SAVE ‘‘RESVAL”’ LINE 10 Delete line 350 As noted, the program could be modified to use the DATA and READ statements. Insert a line 340 with the data as given below, and insert 215 READ X. Change X(N) to X in lines 220 апа 240. 1@ REM ##RESISTOR VALUES INTO ARRAY * x 20 REM жы ІМЕЗ EDITED GUT RFTE R ENTRY OF URLUES == ЗӨ REH жжТНЕМ RESURL PROGRAM Е NTERED xx да DIM X113? ue 50 LPRINT “ARRAY VALUE 60 LPRINT TO XA. VL oam ве LPRINT a te TE зе INPUT X tL. 18090 LPRINT TAB т;хаз 110 NEXT L ARRAY VALUE "ТЕГҮ отын о $ “ RRMA KKK KX май a? uà чн m 0 19 REM xRESURL x 20 PRINT "RESURL" 48 PRIN! "PROGRAM DERIVES PREF ERRED VALUE"; ТАБ Ө; “OF RESISTOR FROM INPUT"; TAB ә; “VOLTAGE AND C URRENT VALUES" 50 PRINT _ > $09 PRINT “PREFERRED UALULECS STO RED IN ";THB е; “ARRAY . DD NOT REUN PROGRAH.USE"'; TRB в; “сото 100." 79 PRINT “SAVE WITH GOTO 340.' ба PAUSE быб 180 PRINT SYOLTAGE ws ise PRINT TAB 128;U;" VOLTS" 140 PRINT “CURRENT т”; 160 PRINT TAB 12,;,1;" AMPS” 170 LET R-INT (.Мх106/1) 7100 1500 PRINT "RD = зан “ACTURL RESISTANCE "; t's .. H +: әде LET L=INT (LM Rz2. 303} -1 210 FOR N=1 FO is 220 IF Ri=X (Ы) 108x*x«L THEN СОТО 230 NEXT N 243 LET x=X (N) z10 жж 258 Ре "PREFERRED RESISTOR: 53 >- Ж? . а. C .. 260 PRINT “GIVES CURRENT "; INT (Uuxl28Q^7X)7100;" AHF 505 27m PRINT "BND “ІМТ iíUxsecÉelg. ы), „ез. cO атте 232 PRINT сай PRINT “AGAIN? (У мә `` see INPUT Q 310 IF @$="N" THEN STGP 320 CLS 330 сото заг 340 SARVE “RESURS 350 GOTO 1@ 4. Matmult Program multiplies two square matrices. À two-dimensional matrix is stored as a two- dimensional array, with the size input. Matrix multiplication requires the number of columns in one matrix to be equal to the number of rows in the other. The matrices are set up as square arrays of equal size in this program, and nonsquare mtrices may be multiplied by entering 0 for the elements of a row or column which is unused. Users familiar with matrix arithmetic will be able to derive from this program the routines to handle other matrix operations. The method involves nested FOR-NEXT loops, in conjunction with three arrays in this program, the third array holding the resultant matrix. Other points to be noted are the input and error routines. The input routine prompts for inputs by row and column number, and when all elements have been entered the error check subroutine is called, so that the user can check the whole matrix at once. This avoids the possibility of confusion over row/column numbers. REM "MRTHULT'" REM #BETTER IN FRSTs > FAST 10 PRINT "2D MATRIX вич T IP ICA TION", жен ннн ннен + жя +++ ж +++ ++" 20 PRINT AT 3,0; “MULTIPLIES SQ HARE MATRICES." : AT „А; "TO USE F OR NONSQUARE MATRICES” , ENTER e TRIX SIZE ТО ACCOMOLATE”, "ANE ЕМ TER ZEROES.E.G ТО MULTIPLY", Мг = 3) ET". = Жы ” 23 әзі % 38 PRINT’ "use NS ps Haters зге NTERING","1 COLUMN AND i ROW O REST @.",,,ENTER HATAICES 8 ITN =a PRUSE 200 се PRINT AT 21,2,” 43EMTER MRI aa REM 4D INENS TOM ISF 2 оны RESULT MATRICES+ зе DIM Я(5,53 зап DIM B(5,5) 1210 DIM С(5,5) 128 CLS іза PRINT "ENTER MATRI” 3°, , ЕРІ TER @ FOR UNUSED ELEMENTI” 249 FOR F=1 ТО 5 ісе FOR N=1 TO 5 158 sarc AT 21,0; “ROU ";F." со 179 INPUT AIF, м) 50 PRINT AT Ғаз, NxOG-O6,mpmpmifF,Ma 150 NEXT М 2220 NEXT F 210 REM ҰМ IDENTIFIES MATRIA FG adi SUBROUTINE + =зё GOSUB See 2590 PRINT "MATRIX 2” 250 FOR Ғ=1 те 2 270 FOR М1 2580 PRINT Ar 317 5%; “ROW “;F; ”7 со омм ‚м; 239 INPUT ӛсе, м: 39090 PRINT AT Fe3, N#6-6;,8 TF, 506 34g u səə oo. ыы “MATRIX 1 + MATRIX 2 =1 TO Š Poe TG 5 ` на TO S 404 LET СР, М =C Р. МУ eR iF Li ғы: +1@ (ЕТ СР, М) SINT (Clr. N} +1E= + di SLES 428 coon AT ҒұЗ,ыіұб-б; C tF Р dix 339 mr 450 NE _ +58 PRINT AT 21.8; "INPUT Cicory |; RIRUN) OR ECE мб)" i70 INPUT 2% IF Z$z"C" THEN COPY IF Z$="R" THEN RUN GOTO 786 REM «ERROR SUBROLUTINE:x HE PRINT AT $0.0." QRE ALL ENTE : OR NJ)" Gl ШІ л Ci n 4-2, "zr GUOJ Go Hl БФ F Бф-“Ү” THEN RETURN PRINT AT 21.9; "RON нен INT CT ENTRIES?" INPUT EN QR F=1 TO EN PRINT RT 20, n NS AT zi. 9; F $ 21,0; "ERROR “;Ғ; ROW INPUT R puri zd 21.7; COLUMN т“ PRINT AT 21.0. R$: 22.8; “E SEBUT M NUMBER IF M=1 THEN LET R:!R,Ciz IF Mz2 THEN LET EiR,.Z;z PRINT AT ntes Cx#6-6; * E BRx2.C*5-6,N NEXT F PRINT AT 21,0:R$ сото S10 REM #END Gams «LO Uf 33 4 co po eat Qc C т “. ew <.. DU n en em gu cn A C c on Tt cr fl inen enm pe p. eq mp C d D СД f D FE SiC CO <А AOS әәболоцоюш бу ENTER MATRIX 1 ENTER @ FOR UNUSED ELEMENTS i = 5 3 о e a ә ә MATRIX 2 © ә 4 ә a = a a e HARTRIX 1 ж MATRIX 2 GIVES: - e e a32 e а е о e e INPUT CICOPY) ,RIRUN: OR E (END 507 5. Fruit Program simulates a fruit machine. The program allows you to continue playing until your money runs out (which it will eventually) and you can then ‘‘borrow’’ more. Points to be noted in the program are the overprinting of a string to simulate the spinning of the wheels (lines 200 to 230), and the logic used to check wins and amount (if any) won, in lines 250 and 260. The program loops back from line 290 to line 140 unless the money has all gone. Spectrum: Change line 60 to read 60 PAUSE 0. 10 REM "FRUIT" NT 1i rh зә PRINT "YOU HAVE SAP BLE.", “EACH ROLL COSTS 10 PENSE. ай PRINT +anPRVOUTS: = THE Sane PHYS 10Р"; S:°S THE SAME Ege s 40P"; TAB SS "ЕХбЕРТ REROMHICH E SO PRINT ,,"PRESS A HEY TO STA INKEY S$=""" THEN GOTO 6&8 - - 14 4 4 CTI mao th Том Т Qz (SS STN P DM тог гон # x INITIALISE «PRINT +Q + mi fui co 3)! 20 P Pm mmm ПІГ ТТІ HHH x i EBER; T Б | ; RINT AT 19.8; 55 5 То £ + HQ IF INKEYS<¢>°S" THEN GOTO 34 RHEE EEE Gg ә 7) 4 2.0010 1 2 REM ##5ЕТ WIN LINE + + = LET Bnga"t 1-0 FOR Ғсі ТО 3 162 LET A=INT RND +Ë x +: 179 LET Б%-В%- Ж” +A 18: 155 AME #*SPIN WHEELS% 186 RE 1989 LET fs) pw. 200 FOR к=1 TO 1 210 PRINT AT 9.12;F$i01 TG ©) 220 LET F*$=F$íŠ TO »?«rF&il TO ZS; 230 NEXT F 234 REM 235 REM *##PRINT WIN LINES + 256 REM 249 3: PRINT AT 9.12: 5$ + 14393 +484425 = 245 REM #xCHECK WIN: 250 LET U-(BE$£(2)zE$ 3 3 BS 16 (6) Li (Bs (4) =E $ (63 255 REH AMOUNT BONE £ eod LET C=(.18 AND 15-і) 541 +0 & 4,45 3) 4+(1.8 AND W=S AND БЕШ =” те LET C$=C$ (1) STARAS (Vet Ciz \+Сс-.1а) REH Y ңғ. du GDG DAG JIC өпаьовбайь (i SHOE Se олы =] O D EL XxCHECH IF SOLVENT +E RINT RT 3. C$ N Е Cs (Š 9:5 ) >ш.10 THEN FIOI F. + +МОМЕҮ SPENT z £ Eri AT 3,.,0;"' xYOU ARE ERU. TAB ә; “BORRÓ ом £2 TIY OR м! a Mg LS MS="Y"' THEN GOTO әт INT "BETTER LUCK NEXT ТІМ G; s QIU fü FO fO nano TO :m POP ж rho CI Сау nur rm о 990 un i 508 6. Lissajous A program to produce the intricate, interesting and delightful patterns, named after the mathematician who discovered the equation that produces them. You merely enter the values of A, B and C in response to the prompts and watch the patterns develop. Spectrum users can generate more complex patterns than ZX81 users, because of the higher resolution PLOT screen. Spectrum: Change line 80 to read 80 FOR F = 0 TO 200 STEP 2. This defines the number of points to be plotted. You can experiment with different values for STEP if you want more or fewer points plotted. Line 90 needs the two 30s changing to 120, and line 100 the two 20s changing to 80. A and B can both be input with values up to about 10 on the Spectrum, so change the Input prompts to suit. REM #*#LIssAvouar REM PLOTS LISSATQUS PRTTERHN $ 2 З REM Я IS RELATIVE FREQUE HC? B IS REL. FREQ. Х,С 15 Y PHRI BIG MENT “INPUT A (INTEGER 1 T 2@ INPUT A oe FRAN “INPUT E {INTEGER 1 T в SO PRINT "INPUT C (ANY HUMBER Ба INPUT С 50 FOR ғ-о TO 20a 90 LET Y=S3@+S04S5SIN (ConaPIaPsi те LET Xz20420*5IN (BxPIsT»igc 110 PLOT v,x 120 NEXT F "v заза, E ап = 1а ur" = = gd 2" я " N E ie а т > x to `. a в .. "ag "er 7. Line This program gives the computer the capacity to draw a line between specified plot co- ordinates. The Spectrum possesses a LINE instruction that does this automatically, but Spectrum users may be interested in the method, which is the way the LINE instruction automatically calculates the points to plot. The program will run on the Spectrum if line 85 is deleted. As it stands, the program prompts for two sets of X, Y points, giving an error message if the points are out of range. Lines 110 and 120 calculate the X and Y axis differences between the specified points. Line 130 defines the variable A as the greater of these. DX and DY are the increments added to the values of X(1) and Y(1) 509 for plotting. In the loop (F = 1 to ABS A, since A may be negative) DX and DY are decremented or incremented (as X and Y are positive or negative) by the distance to be covered between points, divided by the number of steps needed. The program will accept further inputs as required, but does not provide input prompts (lines 210 to 280). 5 REM "LINE" " iO REM DRAWS LINE BETWEE POIR T.,(XC1),VYCLIIAND POINT ах+ш v 1E 3 1 20 DIM X12) 25 DIM Y (2) 50 FOR Ғ-1 TO 2 ©. -- 40 PRINT “COORDINATES POINT “i со PRINT "A UGPLUSE Т" 50 INPUT Р) 70 PRINT ^ ( "Y VALUE Т” (F) > К 1355 THER PROGRAM AGRIN `` DY =@ 16568 FOR F=1 ТО 65 n 179 PLOT ОРТАҒЫ DY £w ££ 180 LET DX=DX+X/ABS F 190 LET DY= DT te CABS e 2BO NEXT F 219 REM FOR OTHER LINES 220 REH M ркан жїл 230 INPUT X(1) ТОЧНИОТ HS ИШИН 8. Reverse The computer jumbles up a sequence of 9 numbers, and prints these (subroutine line 500) after giving the instructions, by calling subroutine 1000. After each input by the player the subroutine at line 300 is called to print the altered sequence and check if the ordering is complete. If the sequence is correct, control is passed to line 2000 for the end routine, which gives the option of playing again. 18 REM “REVERSE” 20 PRINT TAB 10; "#REVERSEs" зе GOSUB 1000 CLS 45 DIN R (9) 50 PRINT TAB 10;"'xREUERSEx' во PRINT AT 5,5; 510 ге GOSUB See өс LET GOES=Ə ae PRINT AT 15,0; “INPUT NUMBER TO REVERSE 77" 100 INPUT R 110 IF R:1 OR R»9 THEN GOTO 100 120 GOSUB 380 136 REM xxLOOP NEXT GO#* 148 GOTO 100 150 REM =#=# += # +++ + +++ + * + + +++ +++ Ж 160 REH 5020 REM rx*xREUERSE AND СНМЕСКЖжЖ 310 REM +#SEQUENCE xx 315 REM 320 FOR F=1 TO INT (R72) USO LITT T=A tF) S4@ LET ЯР) =A (R-F+1) 3550 LET AC(R-F+1) =T 360 NEXT F 370 LET CORRECT = 3882 PRINT AT 5,5; 390 FOR Fz1 "T 9 400 PRINT atF2); T 410 IF AIFI =F THEN’ LET CORRECT =CORRECT +1 429 NEXT F 4232 LET GOESzGOES—-«41 440 IF CORRECT=9 THEN GOTO 2009 450 RETURN 460 REM #++ ++ +++ ++ +++ +++ ++ ++ +++ 500 REM ##S5ET SEQUENCE #*¥ 510 LET ACL) =INT (RND «933 +1 TO 9 S30 LET R (F) 2INT (RND#9) 41 540 FOR N=F-1 TO 1 STEP -1 550 IF ACF) =яМ) THEN СОТО S30 550 FOR F=1 TO 9 S90 PRINT R(tF),;" ”; 600 NEXT F 6180 RETURN 620 REM =з» ++» ++» ++ +++ 6380 REM 19006 Бен *£*INSTRUCT IONS жж 1820 PRINT COMPUTER GENERATES JUMBLED", "SEQUENCE OF DIGITS 1 TO 9. 1030 PRINT “YOU MUST INPUT A NUM BER 1 ТО 9, 1040 PRINT “AND THIS NUMBER OF D IGITS,","STRHRTING FROM THE LEFTM OST a's "UILL REVERSE.YOU MUST GET 2858 PRINT DIGITS IN ORDER LEFT TO RIGHT.' БЕРЕ PRINT ,, "PRESS R KEY TO STR 1 @ PRINT s "THERE WILL BE A DE TU WHILE”, “SEQUENCE IS CREATED. 10628 PAUSE 4ee00 123290 RETURN 4100 REM #= FF EXF FSH + + +++ +++ +1 ++ REM 5000 REM sxEND ROUTINE 2005 REM AT 20,0; "##SUCCESS IN 2619 WES; GOES#s", "ANOTHER GO? CY м 2030 IF Hao ye THEN сото 2050 SYE 9939 STOP 9. Tools The program shows the principle of a programmer’s toolkit program containing useful program modules. You should add to this basic version any further subroutines or modules you want to have available. The inclusion of the BLOCKDEL program makes 511 editing out any modules not required for a specific program very easy. You may wish to add, for example, a round/justify subroutine for numbers, or a sorting subroutine Note the mnemonic for the error subroutine line number. When you add modules however, use variable names that you are unlikely to use in the program you are developing. Load the program before starting a program on the ZX81. Spectrum: For the Block delete module see BLOCKDEL. For Renumber module and Memory left see Section U of the text. Remember you can use MERGE to enter this program at any point (hence the high line numbers). m gj & Umm 00 S480 S33S6+256*#PEEK 163387-PEEK SexPEERKR 16413; S540 9550 REM REM REM "TOOLS" £slLLUSTRHTES TOOLPRIT a езі ОНД) BEFORE START ++ Fe INPUTTING PROGHHRIX:X *xGO0SUB ERROR FOR =н + *KHESSAGE ##GOTOQ ашаа FOR aL Ock ++ #*#DELETE xxGOTO 9700 ғоя BENUM *xGüOTO S458 FOR MEMORY *LEFT ADO YOUR QUNM ROUTIN£ZI £ £ £ £ £ + £ $ £ + AHA $ $ HAAHA RABE ЕКРОВК =94.00 ERROR MESSAGE 508+ 4 * * Xx X X 3 3 Д < 3 HHH PRINT TAB 7, “#844 INPUT ERROR T); RERSRERHRHH4HHHHH ES” PAUSE 120 REM #xHEMORY LEFT із are SHH HHeHAH HAHAH ++ +++ HSH SSS PRINT “MEMORY LEFT ="; PEE 264325 —;3 "1 = — = ae APPROX,” STOP REM x*BLOCK DELETE:: REM 3 * s š 3*3 š € € s£ š š PRINT “FIRST LINE TO DELETE INPUT ST PRINT "LAST LINE ТО БЕ DE: = INPUT END LET RANM=16589 9560 LET LNUM=2564PEERK RAMNSPEER (НАМ +1) 3570 +2 3530 ЕЕК 9 9560 SLETE BLOCK ауа 3500 IF 25б%РЕЕК БКИМФРЕЕК 1 =9000 THEN GOTO 3832 3512 3520 93530 SUB , сота", 354ea@ IF LNUMZST THEN LET LRBH=RA LET LLEN=PEEK S iRHlh-2!4286037 (RAM +3) um “Бына END THEN GOTO ЭББ RAM=RAN4+¢4+LCEN GOTO 3568 LET LLENsSRAM-*LLEN 2-154 PORE LRAM+I1, INT YILLEN.2986561 POKE LRRHM,LLEN-2SOGsPEER ILR PRINT “INPUT FIRST tei TO > = STOP REM #x#RENUMBER #+# REM ££ £ * * š * $ GR +++ LET mRhüM-zilesaa LET LINE =2@ LEIL ӘТЕРсіе POKE RAM, INT (LINE.2wU6 POKE RAM*«1,i!LINE-z296643P££NH LET RAM=RAM+1 IF PEEK RAMI >o4148 THEN GOTO =RAM+1 = 3770 LET RAN URBI +S LET LINE-LINE-«STEP GOTO 9750 PRINT | SRBEUBEREBA NOW DO Go “LINES STOP 512 10. Blockdel Program enables blocks of program lines to be deleted by a single line entry after the line numbers of the first and last lines of the block (ST and END) to be deleted have been entered (the program can also delete itself!). This is done by taking (line 9550) the start address of the program storage area (RAM) then finding (line 9560) the line number of the first line (LNUM). If this is the line number of the start line, the address of the first byte of the line length storage bytes (= RAM + 2) is stored as LRAM (line 9570). The line length bytes are then PEEKed (line 9580) to find the line length in bytes (LLEN), before the line number is checked in line 9590 to see if it is the last line to be deleted. If it is, control is passed to line 9620. If it is not, RAM is incremented by the line length and four bytes for the program length and line number bytes, to get the address of the start of the next line stored in the memory, and the process is repeated. When the end line number has been located and control passes to 9620, the line length variable LLEN is made equal to the number of bytes between the first and last lines for deletion (this is why LLEN was found before checking if the current line was the last of the block) by setting RAM to be RAM + LLEN, i.e. the address of the end byte of the last line to be deleted. This value, less the address of the line length byte of the first line (stored as LRAM), plus 2 for the program line number bytes of the last line gives the number of bytes to be inserted by the POKEs of lines 9630 and 9640 as the new line length of the first line requiring deletion. The computer now thinks that the lines for deletion are all one huge line, and keying in this line number and pressing NEWLINE (ENTER) will delete the whole block. The program should be loaded for use on a ZX81 from tape before you start working on a program. Spectrum users can use MERGE. Spectrum: Line 9550 (giving the start of the program area) must be changed to read: 9550 LET RAM = PEEK 23635 + 256* PEEK 23636 ле REM “BLOCK CEL 3508 214 **8LOCK CELETES4 3505 R * * +++ т 3510 PRINT "FIRST LINE TO DELETE S528 INPUT ST | к S530 PRINT “LAST LINE ТО Sr Prise S54@ INPUT END assa LET ВАМ=16509 S580 LET LNUM-2SBsPEEK Янә 422” IF LNLIH=ST THEN LET ЬЯ = ssaa LET LLEN=PEER (8816523 PRSA 3=- ЕЕК (RAM+33 S590 IF LNUM=END THEN GOTO Q822 зеса LET RAN=RAN+44+LLEN 2610 GOTO 9560 3620 LET LLEN=RANF+LLEN22-L RM зеза POKE LRAMS1, INT ЕЧ soa 29649 POKE LRAN,LLEN- 256 4PEEA tLe +1) $630 PRINT “INPUT FIRST MG TO Z ELETE BLOCK" S668 STOP 10 REM "“BLOCKDEL" 9500 REM ##ELOCK DELETE жж 2505 REM EEE EH HE жы Ж 2510 PRINT "FIRST LINE TO DELETE $520 INPUT ST 9530 PRINT “LAST LINE ТО BE DELE TED?" 2540 INPUT END 9550 LET RAM=146509 513 2560 LET LNUM=275e% PEEK RAM+ FEE қ CRAM+1 > 9570 IF UNUM=ST THEN LET LRAM=RA M+2 7550 LET LLEN= PEEK (RAM+2)4+254.% PEEK CERAM) 2590 IF LNUM=END THEN GOTO 2620 7400 LET RAM=FRAM+44+LLEN 9510 GOTO 60 7630 LET LLEN=RAM+LLEN+2-L RAM 7640 РОКЕ LFñM+1: INT (LLEN/226) 9650 РОКЕ LRAM:+LLEN-256% PEEK xL RAM+ 1) 9660 PRINT “INPUT FIRST»N/L Tü D ELETE BLOCK" 76470 STOF 11. Coder The computer chooses a four digit code sequence comprised of the digits 1 to 6. You input your guess for this code sequence. The computer prints your guess, checks for the number of digits in the correct place which correspond to the code, storing this as AST (for asterisk), and then checks through the remaining digits for numbers which occur in the code sequence, but are not in the correct place (DOLLAR). These values are then printed. This information helps you to refine your next guess. 15 goes are allowed, and if you haven’t got the code in 15 tries, it is printed out for you. The program is structured with a sequence of calls to subroutines. Note that the code can include repeated digits, and analyse the checking procedures to see how this is dealt with. REM “CODER " GOSUB 1006 REM ТАНА а-а AND xx (Жы LET Neo" 22 345 - 1i! = в“ FOR F=1 LET Z n DENS сават «БҰМҒГАн6,ҙ €i: fos IF MARK=1 THEN GOTO 1:38 LET GUESS=GUESS+21 PRINT RT GUESS +2. 1i Gg: TRE GOSUB сос GOSUEB 608 PRINT AST; TAB : DOLLAR REM ж%ҰЗЕЕ IF 15 TRIES жи + xOR CODE CRRCHEDxrxE* F pe yku e e HUGO бб SEeaqQgqao был Sod J OAM mu vu e» Ct Тае 219 IF AST=4 OR GUESS=1Z> THEN GOTO 2868 220 REM ab icr adi TO NEXT GUESS езе GOTO 11 240 REM ^o наказание най 258 REH 222 REN E *xCHECH INPUTrEE $95 BEN á : I F-L TO LEN &G аша Gg (F) аз THEN 24 om TODE < N аза ЫШТ LET MARAH = 1 440 IF LEN 5Ф<>4 THEN LET ter. 514 450 IF NOT MARK THEN RETORN 4603 Gn 2 NB AT GUESS-«3,.0; 7 ";G$;"7? TRY AGRIN.* a7 PAUSE 480 PRINT AT GUESS-T3,0;" 42a RETURN 435 REM хжхжжғғжхжкжғккккккк ЕМ 5020 REM *=*=F IND NUMBER x + 520 FOR F=1 TO 4 530 IF AS(F)I<>GeiFs THEN ТГ 570 қой REM SSH x yx x z£ x x x x k x EEE 520 REM xxFIND fj HRHUPIEEEE y x еге LET DOLLRARRzO өзе FOR F-1 TO 4 FOR N=1 TO 4 550 z g eth) rop On THEN GOÜTOG LET DOLLAR= DOLLAR +2 LET AS(F) ="X 44 4 CL Qn e guo OGOOGO r m -f G) 2 11 ext RETURN 22 REM хжххккккжккккккк 730 REH 1oo00 EE *3x INSTRUCT IONS + + EM іга PRINT TAB 12; VN SEEKER" | TRE 12; “+СООЕК +; TAB 123;' ‘SEER ER К“ 1@38 PRINT .. “COMPUTER CHOOSES = SEQUENCE ОҒ“,%4 NUNBERS.THIS I= MADE UP OF", "аму OF THE DIGITS i TO а”. “INCLUSIVE. DIGITS MEN EE R LE 1 "YOU INET SEGUENCE 5 TO TRY i Nb “MATCH THE CODE." 1050 PRINT ,..^COMPUTER HILL PRIN T NUMBER OF B.SIGNIFYING CORRECT DIGIT IN". "RIGHT POSITION . CPU, ғ UMBER OF = ,HERNING € DIGIT Із G HESS WHICH 19509 PRINT “OCCURS IN THE гомгазт ERS CODE, , BUT IS NOT IN THE БТ GHT PLACE.‘ 41070 PRINT ,.," PRESS A KEY TS Ek, =; 1280 IF ІМКЕУФ-““ THEN GOTG LGE 1090 RETURN 1192 REM EEEIEE 3 38 ККЕ 5228 REM END ROUT : шо INE x x 5929 НЕМ ast 4 THE? 282 = ч GOTO 205 2023090 PRINT "15 TRIES AND NO Sr: ESS.CODE"."uns "209 5058 ERENT Mec сый: - " e E > è £z. na RTRS CESS ІМ í GUESS, cuo T “ANOTHER Ge Ti i т OR NOS GAME IMPLT 2UTO INPUT MS zasa IF Мф-“У" THEN GOTG Zu 2290 CLS заво ERUNT "DC BYE.” 2350 RE 292930 REM *xx«xxxrxENDEEXExEeEk 3999 STOP "BB GUESS E 1 3 3 GG ts 515 S432 1:2 2342 32 X 5122 т. siloa е 1 13923 | 9 3 бізг i = 1362 1 2 4532 s uk S332 12 4352 з 2 3342 г е 3512 4 0 SUCCESS IN 15 TRIES? RNOTHER GAME? { INPUT Y OR H 12. Plot A simple program to plot a graph of data points, with X and Y values input on the screen. Prompts for X and Y axis minimum and maximum values are made, and string inputs for the axis titles. These are then printed, and the data input is prompted. X and Y values for each data point are entered, which is then plotted, and more data is requested. Spectrum: Change line 310 to read PLOT 124244 * (X- AYy(B- A), 12 + 156 * (Y — C)/(D - С) 2 REM PLOT se дё PRINT TAB 6: BSR SE rei сут ET 2à8 PRINT 3@ PRINT "SET AXIS RANGES" 40 PRINT “INPUT X AXIS MIN. vat SQ INPUT A SA PRINT A 70 PRINT “INPUT X AXIS MECN Ue se INPUT Б за PRINT Б © PRINT “INPUT Y AXIS MIM. UAL а” INPUT с € PRINT “INPUT Y AXIS MAX. VAL 14@ INPUT D D i58 PRINT “INPUT X AXIS TITLE " IT a P іза PRINT X$ 152 PRINT “INPUT Y AXIS TITLE ` “ора INPUT Y$ 210 PRINT Y$ 220 5 230 PRINT AT 21,6;:X$& 249 FOR I-1 TO LEN Y$ 250 PRINT AT I«5,.0;Y&1I1j 592 PRINT AT ә. 228 ERENT S ©; INPUT N т NT AT @,0;" v 266 таат 9 O; “INPUT ` UE. p I rius X-A Z CE; — € y , Seay зда GOTO 279 13. and 14. Bidec Program converts binary numbers to their decimal equivalents. Two programs are given, differing in the conversion procedure applied to the binary number, which is input as a string. The algorithm of BIDEC*2 is more transparent than that of BIDEC. Spectrum users have the facility to input binary numbers directly (using BIN), but this 516 cannot handle numbers input in the course of a program, or generated by a program, in which case a routine of this type is required. BIDEC*2 Spectrum: À not ** in line 50. š REM #BIDECs REM CONVERTS BINARY NUMBERS INTO ee tee 18 "ENTER BINARY FORM" 110 INBUT A$ 158 PRINT Өй IN BINARY I2" 348 LET R=LEN AS 150 (ЕТ NSURL & was 160 FOR Fz2 ТО 17@ LET М S ема. F$ IF) ico NEXT RINT. әде PRINT N;" IN DECIMAL” o REN "BIDECx2" 180 PRINT “INPUT BINARY NUMBER" SØ FOR F=LEN БФ TQ 1 STEP -1 БӘ LET es иши BS i Fl £ xP Та LET P=P+ зе NEXT F oa PRINT B$; “=DECIMNAL “iN 15. Hexdec Program converts hexadecimal numbers up to FFFF (65534 decimal) into decimal. As with DECHEX, the straightforward conversion of a character code to a decimal value which is possible on the ZX81 is more complex on the Spectrum. Line 130 in the ZX81 version uses the value of the loop variable K directly to get the decimal value from the character code. On the Spectrum a counter loop is set up to hold and increment the value of K, and a new variable Z is used to hold the number by which K is to be reduced to give the correct decimal value from the hexadecimal character. Spectrum: Line 50 needs À , not ** Insert 55 PRINT ‘‘ LETTERS MUST BE CAPITALS." Insert 115 LET K = 48: LET Z = 48 Change 120 to read 120 FOR Y =0 TO 15 Change 130 to read 130 IF A(F) = К THEN LET N = ((K- Z)*X)+N Insert 135 LET K=K+1 Insert 136 IF K = 58 THEN LET K = 65:1ЕТ Z = 55 Change 140 to read 140 NEXT Y КЕМ x*HEXLDECrx 4) INT 50 PRINT "ENTER HEXADECIMAL NG "rr omm DA- хх I 11 И wu +°: ++ OO о LEN Ar ODE H$IF; „ЕН ris F} K THEN LET N=i t -2E “Wr TP I T жи X Gia p eu A ` (S € 9 баб) (3 Ж m 4 II Qo -. ээк Бараа л 42 NEXT = (Ji б 1 D H z "n WX Th I9 ";N;" IM DECIMAL. 517 @ PRINT © PRINT "RHGRHIN'?7íN OR Y` © IF INKEYS$="Y" THEN GJOTG SS а STOP 16. Dechex Program converts decimal (base 10) numbers up to 65534 to their four-figure hexadecimal/(base 16) equivalents. Hexadecimal numbers use the digits 0 to 9 plus the letters A to F. This requires a means of deciding which character is to be printed, after the decimal number has been broken down. On the ZX81 this is simple, since the (capital) letters A to F follow directly after the digits in the character code sequence. This is not the case on the Spectrum, and the gap in the sequence must be bypassed. CHRS can then be used to change the decimal values (0 to 15), into which lines 120 to 170 break down the input number, to the appropriate character. Spectrum: Change 190 to read 190 LET X = 48 Insert 205 IF X = 58 THEN LET X = 65 TO 19 IF FiiF)=y THEN LET AR&iF;-5H LET жн x+1 Jj PRINT " IS “AS; IN HEX" PRINT AT ENR т NEWLINE UN AGAIN" Ces p. cana mor iU TO EO EG e [Ú [U R9 ei i RP ро RS F2 1 REM DECHEX аа DIM Aig) сә DIM АФ (4) С за PRINT “DECIMAL BASE TO HENA DECIMAL BASENUMBER CONVERS TION™ 4а PRINT БӘ PRINT "NUMBERS «85555 Gni“ ge PAUSE 35 76 CLS S0 PRINT “INPUT DECINGL UD 0E" ай INPUT М аа PRINT 12 PRINT N; ЕФ LET ACIVI=SINT (Ne 4 O58’ За LET B=N-A(1) £4636 4@ LET ACBi=INT (8-258; ей LET C=E-F (2) +258 ео LET Alsi SINT (O-26s 79^ LET Aid) s=C-A(Ss £16 зе FOR ғ-і TG 4 acd LET X=26 eo FOR Yzà із x e e e e o m a a %0-.| 17. Gridhunt Тһе computer hides itself on ап 8 Бу 8 grid, which is displayed оп the screen. You input your guesses of the co-ordinates, the guessed square is marked, and if not correct the computer gives a prompt for its direction from this square, using compass directions. 4 REM ¥*¥GRIDHUNT ж із PRINT —""iaekütal*sgs зә FOR Xz2 TO 18 STEP 2 24. IF srana TREN COTO 46 ху» 40 PRINT AT 3,X; -";HÍi 14,х; "+ 45 PRINT AT 441,22: "+"; RT xX+1l ,1 G3 а. БО NEXT X 60 LET E=INT (t(RND#53) +1 78 LET М-ІМТ (RND zx: + 1 Зб LET G=lE-1} +N ga LET H=@ 518 108 PRINT AT 3.28; "YOuR GUESS: — "AT 3,20; a ae ia Li@ INPUT 128 PRINT Ят 5,26," ";яЯ; АТ 2,29 з “DOWN?” 130 INPUT D 131 FOR Xz1 TO S 152 PRINT RT 2-«Dzx2,1-24a0*2; Ж. 133 PRINT AT 2+0%+2,1+я+2; "Y 134. NEXT X 135 PRINT AT 2t042,71+AR2S; “ж 14@ PRINT AT 7,24;" ";г;ат 9,20 145 LET М=М+1 150 LET С= 9-1) #642 160 IF C-G THEN сото зай 2 = 190 IF N>D THEN PRINT "S"; 2OD IF N:D THEN PRINT "N"; 216 IF EYR THEN PRINT "E"; 220 IF Е‹А THEN PRINT "UW"; әзе PRINT " “;TRS S2,"OF YOU" 222 PAUSE 2080 250 FOR X=3 TO із Р 300 PRINT “GOT HME";ThB S2,;"IN ~ 19 PRINT AT 20,89; “PRESS A KEY TO PLAY“ see IF INKEYS$="" THEN GOTO S2@ 330 PRINT AT 20,8; 349 CLS 358 GOTO 1G 18. Rescode Program calculates resistor values from inputs of the colour bands on the resistor. Three bands are input, end band first, using the abbreviations given. The first two bands define the basic value and the third the multiplier. 32 BRYBESEOPE "ENTER COLOU У NDEAND FIRST" ee MESS 3e INT айд PRINT “USE CODES AS БЕ ОШ: во PRINT ТАВ 6; “RED RE'; Тағ 6; "BLACK 6L"; TAB 5:"BROUN BR" ; TAB 6; “ORANGE OR’; TAS 65; "YELLOW "YE"; ‚таз 5; “GREEN GR’; TAB 6; “BL МЕ BL"; TAB 6; "UIOLET VI’; TAB & ; GREY Gv" TAS o; "WHITE UH",T nb Б; "GOLD GO"; TPE ё; “SILVER 5 X^ вә FOR A=1 TO 3 Ж. PRINT "COLOUR ";A; "7 n2 ве INPUT C$ өй PRINT C$ 100 IF C$-2"BK" THEN LET U=@ 110 IF CS$-"BR" THEN LET Uzi 12@ IF Сф= “НЕ” THEN LET Uz2 130 IF C$-"0R" THEN LET Uz3 140 IF C#="VYE" THEN LET V=d 150 IF C#="GR" THEN LET Ч=5 160 IF С%-"Еі. THEN LET V=s 170 IF Сж-"МИІ" THEN LET М-? 48@ IF cCH="GY" THEN LET УӘ 190 IF C$-"UH' THEN LET Uz9 оаа IF C#="GO" THEN LET U-i0 210 IF Cs” SI" THEN LET іші эра IF n-i THEN LET F= 2:30 IF R=2 THEN LET FoF He LG+u 24G NEXT A 250 METNT “RESISTANCE VALUE IS bea IF U9 THEN БОТО Зва 519 S10 PRINT " OHNS" S6Q PRINT Fev; 370 PRINT " OGHHS 19. Marker Program produces a marksheet for the pupils in a class after exam results are entered in five subjects, set in this program as English, Maths, French, Computing and Biology. The average mark for each pupil is calculated, and a grade breakdown of the results is printed, giving the total number of pupils in each grade. The grades are defined as: 45% or less FAIL 45 to 7596 PASS More than 75% DISTINCTION As initialised, the program allows up to ten pupils in each class. A pupil name is entered with the results in each of the subjects, and the average calculated. When all entries have been made, END is entered and the subjects, results and grades for each pupil are printed. The grade breakdown is then given of the number of pupils in each grade for each subject. 1 REM “MARKER” 5 LET Ti-e S LET Te=8 7 LET Ta=e , 8 LET Z$-z"END да DIM AB$ir18,20) 20 DIM RIID) 25 DIM Di5! вв DIM PS: 27 DIM F (Š За БІН S$1í5,1i0) да DIM H(3i@ S) 52 PRINT “MARK SHEET" GE PRINT “аға, т^ PRINT "" зә PRINT “С 100 LET Ісі іле LET Com РО КЕТ SEII: "ENGL FSH” АЗА LET ss te) =" МАТН" TES КЕТ 59:95 =“FRENCH" 150 LET S$ it? -“СӘМРОТІМС" 160 LEFT S$tS) ="BIOLOGY" 22020 PRINT “EN ЕН NAME CENTER Ef p TO FINISH): ^" 21ı1@ INPUT RSet ере PRINT REL ONHH а” ғ» езе IF mn$i1? езе SOSUE ive 250 LET Ісізі ese LET C=C+1 255 CLS 268 сота гае Sag REM CALC RVERAGES элт соғу THEN бОТО See 2) +R t L) ос өзе PRINT "МАМЕ :"; ABET? 6249 PRINT "SUBJECT"; TAB iS; “HAN K"; TAR 2@; “GRAPE” сест eater ortega 638 FOR U=1 TO 5 6535 IF М(І,о3575 THEN GOSUB 2ee 626 IF MET, 42 245 AND MOI, N 275 THEN GOSUR 222080 " ad YF Mi, <=45 THEN GOSUR 24 520 GEA PRINT ASE; TAS i15; MCI, iT AB 22; =s 6S@ NEXT < 665 PRINT "" 666 PRINT “AVERAGE= “JANS 667 PAUSE sae 668 COPY өзе CLS 67e NENT X 700 PRINT “GRADE BREAKDOWN BY = UBJECT “ ТЇЙ PRINT “-------------------- ?29 PRINT “SUBUECT'; TAB 25; "PD IS T.“ FRB PZ; PRSS“, TRE 27; “FRILL” 725 PRINT ~” тз БОК (u=: FO 740 PRINT 23 (49; TTAB ір TRB 5e LET Ті-тізб cay Zëw LET Fe=TesP U.i) тта LET TAs Farr 522 S20 PRINT “TOTAL”; TAS 15; 74; TAS 22;T2; TAS 27,T3 ase STOP BBR ROM INPUT гата ӘӘ FOR =i TO 3 ДЕР. қ аын "USUBRBJECT “;5%%0»;” MR 1858 INPUT Hr.) Өте PRINT Hül,.) Loan NEXT М 11 RETURN зала REM DISTINCTION SQUIB LEF G$= DISTINCTION" 2020A LET о =O tt + 1 203a RETURN 2200 REH PASS. гїї LEF G$ =“ PRES” 2220 LET FP XG =P (=1 AND D<=5>1 THEN СОТО со GOSUB 250 TO 20 ге SEN ` ¿pra AL то 3203 Әй IF M>=1 AND М<-іг THEN сото іре GQOSUB 250 110 сото 74 i209 PRINT “YEAR?T‘AS LAST 2 DIGI 521 130 INPUT Y 140 IF vY»10 AND Y<9S THEN GOTO ісе GOSUB 2560 169 GOTO 12€ 170 REM CHECK DRY М5 MONTHS 180 REM xLERHP ‘EARS | 1a! IF ІМТ (t¥4i3@8) 24) <> (Y +1ƏG о) /4 AND M=2 AND с=з THEN GOTO сб REM SHORT MONTHS 210 IF NOT ({M=2 AND D:28) OR t OR M=6 GR M-9 OR hH-11) AND Б-311: THEN GOTO 249 220 GOSUB 250 238 GOTO 19 240 RETURN 245 REM #=# =s X 3 + Xx x zy x x x Z= 3 3 % + X ЖЖ 249 REM szszsERROR NOTICE SUBS 250 PRINT “*###INPUT ERRORSss"," PLERSE FOLLOW INSTRUCTIONS", "ВЕ – INPUT REQUESTED DATA.” 260 PAUSE 180 270 CLS 250 RETURN зой REM *¥##PROGRAM HERE ТО USE INPUT ROUTINESs*x 318 REM #EXAMPLEs E 320 PRINT “YOUR BIRTHDAY" 3360 GOSUE 10 2 lI b. PRINT “BIRTHDATE: "`; BD; "+"; Б 21. Headliner Program prints banner headlines on the printer, using the character arrays stored in ROM. As listed, the program allows the inverse characters of the ZX81 to be used, accessing the normal character (line 13@) to get the pattern of bits, but reversing this (1.е. swapping black for white) for printing (line 560). This procedure is not possible on the Spectrum, since the inverse forms are not included in the character set. The basis of the program is the reading of the character arrays (as with the BIGPRINT program in Unit U3 of the main text), but with the additional complication of reading the first bit of each byte, then the second bit of each byte, and so on, in order to print a character with a sequence of printer lines. Spectrum: Delete lines 40, 120. 130, 550, 560 Change line 160 to read: 160 LET L = PEEK (15360 + C+8 * CODE L$) L REM *#HEADLINER: 10 PRINT TRE 5; "im ез PRINT ,,; PROGRAM TO PRODUC E LARGE PRINT", "AS HERCLINES ALG NG PRINTER PAPER” GO PRINT ,,;" "INPUT ANY LEN&TH STRING." 40 PRINT ,,;" YO: MAY USE ALL L ETTERS , NUMBERS", “AND GRAPHICS.” Se REM CIM RRRRY ТО STORE LETT во DIM Яќ54.) 70 INPUT U$ ва FAST Эе FOR Е-і TO LEN U$ 100 REM TRKE LETTER 118 LET Іі %-ііФІҒ) 124 REH IF CHR INVERSE THEN SURF FOR NORMAL FORM азе IF CODE L$»63 THEN LET L§$=C HR* (CODE ЦР) -126) 140 REN SET кәм COGOZ3 156 FOR с-а YO 7 ¿150 LET L-PEEK (7680«C45sCODE L j e 522 170 REM GET BINARY INTO BERRY 180 FOR B-1 TO Gg 190 IF L-exsINT (iL^2)-1 THEN GOT 200 LET AIiSsC+B)} =o 210 GOTO 238 22 LET RíOGxc-5)-1 230 LET L-IN!T (1/23 240 NEXT B 254 NEXT С рес GOSUB саз 278 NEXT F сазда REM PRINT SUSROUT INE 510 REM REVERSE LOOPS 52 FOR X=8 TO 1 STEP -1 S3@ LET niz fe 540 FOR @ STEP -1 550 REM REVERSE IF CHR INVERTED ВЕРОНЕ See IF CODE U$ (F?) 5655 THEN LET A {т €*5O-X) =NOT ACY x€ +X: 2; REM PUT ONE ROR GF CHR INTO Ag оза LF R (Y*S+xXx)=1 THEN LET A$=A S90 IF RO xG4X)-0 THEN LET AS=R AS S20 LPRINT RS Do0 NEXT X 64@ RETURN 22. Input Program checks a number input as a string. This is a useful way to input numbers, as an error will not cause a program halt, as will happen, for instance, if a numeric input contains more than one decimal point. The program is listed as an input check for decimal currency, but is easily modified to suit any numeric input of a known form. The string input is checked by the subroutine at line 200, each character in turn being checked by means of its code to ensure it is either a digit or a decimal point. To check for multiple d.p.’s the counter S is incremented each time one is encountered. M is set equal to the number of digits before the d.p. A check is then made for S being greater than 1 (non-numeric character or more than one decimal place), @ (no d.p.), and for more than two digits after the d.p. Any error sends control to the error subroutine at line 400. This requests a re-input the number. The error check subroutine is then called recursively to check this input. A correct input will pass control back to the main program, where the user is given the opportunity to check that the input value is correct. 1 REM "INPUT'" STRING INPUT CHELNED RS REM *#MARKERS x 16 LET 5-0 E ken ss М EMPTY LINE: 20 LET E&-" £ ** 30 PRINT “ENTER BHOUNT . ENTER OUNDS.","FULLSTOP,P E E аа INPUT NG SPR Tec ET OFFER VALUE CRECH E entry Бай SMS SQ тысы Ut ID. Vt < ^ x` :yT x Г. ГЕ ТЕМ,Е TO RE-EN ж Т тнт 78 INPUT аф SQ IF Ag="C" THEN GOTO 178 30 IF A$="E" THEN GOTO асс ,480 PRINT AT 20,9; “FOLLOM INSTR 116 GoTo за 120 PRINT AT 29.9;EF&: ES 130 PRINT AT 20.0. “ENTER ЗІ ЕЕЕ T UBLUE." 140 INPUT N$ 150 PRINT AT зә.о;ғе:ғе 923 160 GOSUB 200 170 Crs 150 PRINT “END OF PROGRAM 130 GOTO 999 133 REM *ERROR CHECK + 200 LET L=LEN N 210 FOR F=1 TG L 219 REM *CHECK NON-NOÜMEDRIL CRET 220 IF CODE a. oa” OGR СТИХЕ ME F)»37 THEN LET S22 2293 REM xCHECH ҒІҢА ЕТЕ ә: IF МФХЕЗ =". THEN LET 5-е еі 240 am £L. p^ z"," THEN LET rtzF B= ЗЕ Ж OR 5,2 Gh £=& THE ы GOSUE 486 333 REM sERROR FOUND: ғас PEINT AT 23, Oi“ £IMFLIIT INURL IDsRE-EMTER URLUÉ" 418 INPUT H$ LET © 412 E = = 412 LET Мб 420 GOSUB 200 430 RETURN 299 REM END 23. Asteroids The program puts you at the helm of a Mars shuttle disguised as an asterisk. Avoiding the Nova Heat you have to weave through the strangely square low albedo asteroids that look surprisingly like inverse squares. Your controls are fairly minimal - not much money on the Mars run smuggling algae these days, so you have a button marked 1 to go left and one marked 0 to go right. The program cannot be simply modified for the Spectrum so this listing applies to the ZX81 only. = REM "ASTERDIDS" 10 PRINT "x«ASTERDIDZ3«" 20 PRINT Р 30 FRINT “AVOID BLACK ASTEROID 40 PRINT “YOU STEER YOUR SHIF сж)" SO FRINT "BY PRESSING 1 TO GO LEFT" во РЕІМТ “AND 0 TO GO RIGHT" 70 PAUSE 400 во CLS 90 РПКЕ 1641538 100 LET 50 110 LET C=10 120 SCROLL 130 PRINT AT 9230; 140 IF PEEK ( PEEK oe M ыы F' ЕЕК 16399)<125 THEN GOTO 220 150 PRINT "же 160, LET L=C 170 IF INKEY$ ="" THEN GOTO 190 180 LET Г-С- (C>1 AND INKEY$ ="1 "y+(C 212 AND ІМКЕҮФ ="0") 190 PRINT АТ 8» ЕМО *20; "m" 200 LET 3-241 210 PRINT AT Soli" " 220 GOTO 120 524 250 260 270 220 290 300 210 РЕІМТ 5 PAUSE 250 CLS PRINT “PRESS NEWLINE FOR" PRINT "ANOTHER GAME" INFLIT A$ IF AS="" THEN GOTO ВО 525 Peter Morse is Professor and Head of Computer Science at the Polytechnic of Central London. He has wide ranging teaching, research and consultant activities in the fields of digital systems, software engineering and computer education. Ian Adamson is an educational consultant active in the design of technical and scientific courses, and the associated buildings, laboratories and equipment, working mainly on overseas projects. Ben Anrep is a Senior Programmer working оп microprocessor system development and software with the Computer Centre of the PCL. Brian Hancock is Senior Lecturer in Computer Science. His teaching and research activities include programming methods and the operation of computer courses for schoolteachers. The Essential Guide to Timex/Sinclair Home Computers is the only comprehensive guide to the world's best-selling and most inexpensive home computer, the Timex/Sinclair 1000 (also known as the Sinclair ZX81) and the new Timex/Sinciair 2000. The authors, highly respected computer science prolessors and consultants, take you beyond any instruction manual and present everything you need to know, in easy- to-understand language, about hardware, software and programming skills. The Essential Guide to Timex/Sinclair Home Computers covers all aspects of operating and programming Timex/Sinclair home com- puters, including: turning the machine on (not as obvious as you think!); the basics and the five points of Sinclair BASIC; designing programs incorporating subroutines, loops and nested loops; using strings, lists and arrays; generating graphics on the T/S 1000 and color graphics on the T/S 2000; addressing the computers memory with PEEK and POKE commands; and special tips on editing and debugging techniques. It also includes a complete program library, as well as many exercise and game programs to use while you learn, a section on applications, a simple guide to error codes, a special summary of Sinclair BASIC commands, an expianation of character sets and codes, and much more. This is the oniy book you will ever need for your Timex/Sinclair 1000 or 2000, and the perfect tool for building program- ming confidence no matter what kind of computer you own. oe Д |01/005і0Пе Book Cover by Zimmerman Я Published by Simon & Schuster, Inc. Foyster Design New York “Timex” is a trademark of Timex Computer Corporation. “Sinclair” is a trademark of Sinclair Research Ltd. Neither the author nor the publisher is affiliated with Timex Computer Corpora- tion or Sinclair Research Ltd., and neither Timex Computer Corporation nor Sinclair Research Ltd. has authorized the publication of this book. 0553-0550 $8.95 0-671-47069-8