home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Basic / MAXONB32.DMS / in.adf / docs.lha / Tutorial < prev   
Encoding:
Text File  |  1994-10-31  |  186.1 KB  |  6,053 lines

  1.  
  2.  
  3.                    Chapter 2
  4.  
  5.  
  6.                    Tutorials
  7.  
  8.  
  9.                        
  10.  
  11.  
  12. BASIC is just one of many computer languages
  13. that you can buy for your Amiga computer (you
  14. could contact HiSoft for up to date details of
  15. the range available) but BASIC is deservedly
  16. popular for its ease of use and the speed with
  17. which a beginner can learn to produce results.
  18. On the other hand there are two common
  19. criticisms of BASIC. Firstly, many people feel
  20. that its very flexibility and tolerance
  21. encourages poor programming habits compared to
  22. highly structured languages such as Pascal.
  23. Secondly, BASIC is often the slowest language
  24. you can use, which makes it unsuitable for many
  25. time-dependent applications such as games and
  26. graphics.
  27. Our new BASIC, MaxonBASIC 3, goes a long way
  28. towards solving both of these problems. We have
  29. taken the best qualities from Microsoft BASIC,
  30. Pascal and other languages and combined them
  31. together to produce an implementation that is
  32. capable of running traditional BASIC programs
  33. but can also be used to produce a source that
  34. is highly structured, easy to follow, and
  35. simpler to debug. It is also extremely
  36. powerful, giving you the ability to control
  37. almost every feature of your computer, hardware
  38. and softwareÉ and, above all, it is fast.
  39. Many people familiar with older versions of the
  40. language will have some re-learning to do. Bad
  41. habits and unnecessary features, such as line
  42. numbers, can now be forgotten, although you can
  43. use line numbers if you really want to.
  44. MaxonBASIC does not mind if you want to take
  45. things gently and continue using them for a
  46. while.
  47. To help you get to grips with BASIC and, in
  48. particular, MaxonBASIC, we have written a
  49. tutorial which forms the rest of this chapter;
  50. this is aimed at users who have not used BASIC
  51. very much before and starts from first
  52. principles; experienced users may find it
  53. useful as a refresher course.
  54.   
  55.   Throughout the tutorials you will see some
  56.   text   marked  with  sidebars,   as   this
  57.   paragraph  is  marked. These passages  are
  58.   diversions  which need  not  be  read  the
  59.   first    time    through    but    contain
  60.   supplementary information which you should
  61.   find  useful  once  you have  become  more
  62.   confident with MaxonBASIC.
  63.  
  64.  
  65. BASIC Tutorial
  66.  
  67. The examples used in the following tutorial are
  68. designed to illustrate the power of MaxonBASIC.
  69. They will therefore tend to use its structured
  70. elements as much as possible, but do remember
  71. that you can also type in many programs from
  72. books and magazines that would work with more
  73. inferior versions of BASIC. They should run,
  74. and run much faster, with hardly any alteration
  75. at all; if there are problems, MaxonBASIC will
  76. point you towards which lines are causing the
  77. trouble, quickly and simply.
  78. All computer programs are simply tools which
  79. allow us to control the actions and reactions
  80. of the computer itself. MaxonBASIC has been
  81. written to be as compatible as possible with
  82. several different versions of the language -
  83. notably AmigaBASIC that came supplied with
  84. older Amiga´s and also Microsoft QuickBASIC
  85. which is one of the most highly respected
  86. implementations of the language available for
  87. the IBM PC range of computers (and compatible
  88. machines). Language elements have also been
  89. added from Borland´s Turbo Basic for the PC.
  90. We aimed at this compatibility for two reasons.
  91. Firstly, anyone who has already learnt to
  92. program in one of these different versions of
  93. BASIC will be quickly able to work with the
  94. MaxonBASIC language. Secondly, programs that
  95. are have already been written using these
  96. versions will run with little or no alteration
  97. under MaxonBASIC (but of course they should run
  98. much faster!).
  99. The latter feature is particularly important to
  100. anyone who intends to run a specific program,
  101. one that was originally intended for the IBM PC
  102. for example. It will also allow anyone who
  103. wishes to learn more about programming to buy
  104. tutorial books that were aimed to be used with
  105. one of these versions of the language.
  106. However, for anyone who is new to programming
  107. it is not all good news. MaxonBASIC has had to
  108. conform to the language standards used by at
  109. least two different systems, and these in turn
  110. have built upon previous versions of BASIC and
  111. so on. As a result not all commands are as self
  112. explanatory or as easy to use as we, or you,
  113. might wish. One area of difficulty is that,
  114. because MaxonBASIC is compatible with so many
  115. other BASICs, it has a large number of Reserved
  116. Words that you should avoid using as labels or
  117. variables e.g.
  118.  
  119. Loop:
  120. PRINT "Welcome to MaxonBASIC!"
  121. GOTO Loop
  122. If you typed this program in and tried to
  123. execute it using MaxonBASIC, you would find
  124. that an error will occur on line 3. This is
  125. because Loop is a reserved word in MaxonBASIC
  126. (you will learn how to use it later) and thus
  127. you cannot use it as a label or variable. You
  128. must watch out for this type of error since you
  129. can easily confuse MaxonBASIC by using its
  130. reserved words incorrectly. See Appendix C for
  131. a list of the Reserved Words.
  132.   
  133.   Experienced programmers, who are sure that
  134.   they  know what they are doing, can remove
  135.   a  Reserved  Word so that it  can  be  re-
  136.   defined. You do this with a line like:
  137.   
  138.   REM $DISABLE PRINT
  139.   
  140.   to  remove  PRINT from the  Reserved  Word
  141.   list.  You  can  then create  a  new  sub-
  142.   program or function called PRINT.
  143. This tutorial is intended to be a complement to
  144. the Command Reference section of this manual.
  145. Unlike the latter, here keywords are grouped
  146. logically by their general function rather than
  147. alphabetically. We have tried not to duplicate
  148. information that is perfectly obvious from the
  149. Command Reference, but rather to summarise the
  150. way that certain keywords are related to each
  151. other and interact with each other. At times it
  152. has been inevitable to make forward references
  153. to keywords or programming techniques that have
  154. not yet been covered in detail, but we have
  155. tried to keep these instances to a minimum.
  156. Please consult the Command Reference chapter
  157. frequently as you work through this tutorial -
  158. you will find understanding will dawn more
  159. quickly and more easily if you supplement your
  160. knowledge in this way.
  161. After the first few programs presented in this
  162. tutorial it will be assumed that you know how
  163. to use the MaxonBASIC editor; the various
  164. demonstration programs will be presented
  165. without constant reminders of how to enter and
  166. run them although we will give examples of
  167. editing techniques etc. from time to time. If
  168. you need further help, you should consult
  169. Chapter 3 on using the editor.
  170.  
  171.  
  172. The Building Blocks of BASIC
  173.  
  174. We can look on each component of the BASIC
  175. language as a building block from which we can,
  176. step by step, construct an entire program. As
  177. we shall see later, the structured aspects of
  178. MaxonBASIC make it particularly easy to develop
  179. very long and complex tasks as a collection of
  180. small modules, each one of which performs a
  181. small part of the whole and which can be tested
  182. and perfected in isolation.
  183. The smallest component of the BASIC programming
  184. language is known as a keyword. Each of the
  185. keywords does a certain job, although some of
  186. them must first be given some information to
  187. work on, and many of them only function when
  188. used in conjunction with certain others.
  189.  
  190. For your reference, a list of all keywords used
  191. by MaxonBASIC is given in Appendix C. You must
  192. ensure that you do not try to use any of these
  193. words to represent variable or subroutine names
  194. or MaxonBASIC will become confused as to which
  195. you really mean.
  196. The function and syntax of every single keyword
  197. will be detailed in the Command Reference. This
  198. tutorial section will not attempt to cover
  199. every one of these again, but rather try to
  200. illustrate the way that some of these building
  201. blocks can be joined together into useful
  202. routines.
  203. The most important thing is that you learn to
  204. ´think like a programmer´. Once you begin to
  205. see how small programs work, how the individual
  206. commands fit together to produce the desired
  207. end result, you will quickly be able to pick up
  208. new keywords as and when you need them.
  209.  
  210.  
  211. Some Simple Commands
  212.  
  213.  
  214. There are many very simple tasks you can ask
  215. your computer to do which really form the
  216. 4bread and butter´ of computer programs. The
  217. simplest example to start with is
  218. unquestionably a command like the BEEP command
  219. which, no prizes here, causes the computer to
  220. attract the user´s attention. We´ll try it now
  221. and enter a short program.
  222. Start by locating the HBasic2 file on your
  223. working disk or hard disk (see Chapter 1), then
  224. double-click with the mouse on the HBasic2 icon
  225. to run MaxonBASIC.
  226. After a short while, the editor window will
  227. appear.
  228. Now type the following, pressing the Return key
  229. at the end of each line:
  230.  
  231.  
  232. PRINT "Please wait for the beep ..."
  233. BEEP
  234.  
  235.  
  236. Now hold down the right mouse button and move
  237. the mouse up to the Program menu and, holding
  238. the button down, move the mouse until you have
  239. selected the Run command. Now release the
  240. button.
  241. This will run your program which should open a
  242. window, display its message and beep (flash the
  243. screen) É impressed?
  244. Ok, but it was simple to do.
  245. Press a key and select New from the Project
  246. menu to create a new window; we´ll move
  247. straight on to a more complex (and Amiga
  248. specific) command: LINE draws a line on the
  249. screen. By looking in the Command Reference
  250. chapter you will see that this keyword can be
  251. given several parameters which control the
  252. start location and finish location of the line.
  253. We will be dealing with LINE and other graphics
  254. commands again later in the tutorial, so do not
  255. try and take it all in at this stage. Just try
  256. this simple command for comparison with BEEP.
  257. Remember that it does not matter whether you
  258. type the MaxonBASIC commands in upper or lower
  259. case or even a mixture of the two; LINE, line
  260. and Line are all the same to MaxonBASIC.
  261.   
  262.   The   editor  will  upper-case  MaxonBASIC
  263.   Reserved  Words automatically if you  have
  264.   selected  Show  Keywords in the  SettingsÉ
  265.   requester from the Settings menu. This  is
  266.   useful  as a quick syntax check after  you
  267.   have completed each line.
  268.   
  269.   
  270.  
  271. PRINT "Just a short line ..."
  272. LINE (100, 100) - (200, 200)
  273.  
  274. You can run this as before, by selecting Run
  275. from the Program menu or you can run it by
  276. using a keyboard shortcut, Ctrl-X - it achieves
  277. exactly the same as selecting Run but some
  278. people prefer the keyboard to the mouse. There
  279. are many keyboard shortcuts within the
  280. MaxonBASIC editor.
  281. Press a key so that you are back looking at the
  282. source code of the LINE program, then select
  283. New from the Project menu to create a new
  284. window. By this point we have several windows
  285. open, so click in the Close box, at the top
  286. left of the window, of our two earlier programs
  287. to forget them - click Lose when the requester
  288. appears.
  289. The commands that you can give the computer
  290. must be presented in a fairly rigidly defined
  291. style and format known as the command syntax.
  292. The correct syntax for every command you use is
  293. given in the Command Reference chapter. Program
  294. syntax can be compared to the grammar of the
  295. English (or any other) language; if you want to
  296. make yourself understood to other people you
  297. should speak and write reasonably correct
  298. English. In the same way, you must be careful
  299. to write your BASIC programs correctly for
  300. MaxonBASIC to understand what you mean.
  301. One thing computers are very poor at (and
  302. people are normally rather good at) is guessing
  303. what we mean when we present them with
  304. ambiguous or incomplete instructions (which is
  305. why a computer can do many engineering tasks
  306. but will probably never have a career in
  307. politics).
  308. For example we cannot use the commands:
  309.  
  310.  
  311. LINE 100 100 200 200
  312. LINE 100:100:200:200
  313. LINE (100)(100)(200)(200)
  314.  
  315.  
  316. and expect the computer to do what we wanted,
  317. we must obey its own rules and not invent our
  318. own. Try typing in the first line above and
  319. running it (Ctrl-X, remember?).
  320. You should find that an error requester appears
  321. and you are asked to Continue, OK or Stop?
  322. Select Stop and you will be returned to your
  323. source code window.
  324.                        
  325.                        
  326. Something has gone wrong, the program did not
  327. run. Look to the top right of the window, you
  328. should see an error message (Open bracket
  329. expected instead of 100) - was that what you
  330. expected? MaxonBASIC knows what it wants and
  331. has told you quite clearly - unfortunately,
  332. error messages are not always so obvious.
  333. Errors in syntax rather than logic are among
  334. the most common mistakes beginners to computing
  335. make. Where it can, MaxonBASIC will make every
  336. attempt to catch these errors and explain to
  337. you what it cannot understand (if you think
  338. about it, to explain one´s own
  339. misunderstandings is something of a paradox so
  340. please be tolerant if MaxonBASIC does not
  341. always highlight the exact problem).
  342. At this stage it is useful to cover a valuable
  343. keyword; the REM or ´do nothing´ command. REM
  344. is actually short for REMark and anything you
  345. type on a program line after this keyword will
  346. be ignored by MaxonBASIC, whether it contains
  347. valid keywords or just plain ordinary English.
  348. The main use of the REM command is to allow you
  349. to add notes to your program which explain what
  350. it is the next section of the program is
  351. intended to do.
  352. REM is also invaluable for catching obscure
  353. mistakes (or ´bugs´) in your program where you
  354. have got the syntax of the program correct but
  355. there is an error in the logic which the
  356. compiler may not be able to spot. If you have
  357. commented your program clearly it is often
  358. possible to quickly isolate and identify where
  359. the problem lies.
  360.   
  361.   REMs  can  also  be used to  ´switch  off´
  362.   sections  of  the program  that  you  have
  363.   tested  and know work correctly,  so  that
  364.   the  parts still under development can  be
  365.   run in isolation.
  366. There is an abbreviation for REM - the ´
  367. (single quote/apostrophe) mark. This is
  368. particularly useful for commenting out program
  369. lines, because it is quicker to insert.
  370. Much more useful than our friends BEEP and
  371. LINE, but also more complex, is the PRINT
  372. command which is used to get the computer to
  373. put information on the screen, as we have
  374. already seen above. Extremely impressive
  375. tabular effects are possible using the most
  376. sophisticated options of this command but,
  377. since it is also an instruction that you will
  378. be using almost every time you program in
  379. BASIC, we might as well learn it quickly - it
  380. is after all one of the few means by which we
  381. can get the computer to tell us the results of
  382. any calculations or tests it has performed.
  383. In its simplest form the PRINT command needs no
  384. parameters beyond some indication of exactly
  385. what it is that you want displayed. One way to
  386. try it out is to use the computer as a, rather
  387. expensive, pocket calculator. Try entering some
  388. of the following short commands. Remember, use
  389. Ctrl-X to run the program and Close or AK to
  390. clear out the text.
  391. For deleting short programs, alternatives to
  392. closing the window are: position the text
  393. cursor at the end of the line and use the
  394. Backspace key repeatedly or position the cursor
  395. within the line and use the delete line
  396. command, which is Ctrl-Y.
  397.  
  398.  
  399. PRINT 23+45
  400. PRINT 12*6
  401. PRINT 99/9
  402.  
  403.  
  404. Of course it is possible to print text as well
  405. as numbers as so:
  406.  
  407.  
  408. PRINT "Ten times twenty six equals"
  409. PRINT 10*26
  410.  
  411.  
  412. To signal to BASIC that you want it to print
  413. the text as it is given, rather than attempting
  414. to look the words up as potential numeric
  415. variables (see below) the text must be enclosed
  416. in double quotes (""). Again this is an example
  417. of the need to use the correct syntax to avoid
  418. ambiguity.
  419.  
  420.  
  421. Layout of Programs
  422.  
  423. Before we get too involved it is worth pointing
  424. out some simple points about the layout of
  425. BASIC programs.
  426. The highly advanced structured programming
  427. features provided by MaxonBASIC are intended
  428. primarily to allow the programmer to work in a
  429. clearly defined and modular way. These make it
  430. very much easier to follow the logic of what is
  431. trying to be achieved. However it is not only
  432. the language keywords that make this possible;
  433. the way that the listing is organised, on
  434. screen or on paper, is very important so that
  435. the programs are easy to follow.
  436. MaxonBASIC does not care whether the keywords
  437. you type are in upper or lower case, but they
  438. will be much easier for you to spot and to
  439. follow if upper case is used; in fact the
  440. editor helps you by upper-casing keywords
  441. automatically if you check Show Keywords in the
  442. SettingsÉ requester on the Settings menu. The
  443. editor also does not mind how many extra spaces
  444. are used to indent different lines of the
  445. listing - make full use of this feature and set
  446. out your modules so that the eye can easily
  447. follow the hierarchy of the program. Again the
  448. editor can help by automatically indenting
  449. lines; this is described in more detail later
  450. on.
  451. Like all modern versions of BASIC it is
  452. possible to put more than one command on each
  453. line, as long as each command is separated from
  454. the next by the colon character (:); this can
  455. be very useful to maintain the logic of the
  456. program.
  457. Unlike many versions of the language,
  458. MaxonBASIC does not need line numbers; you can
  459. use them if you wish or avoid them like the
  460. plague!
  461.  
  462.  
  463. Using Simple Variables
  464.  
  465.  
  466. The power of a BASIC calculator program such as
  467. we have written above can be greatly increased
  468. by the use of simple numeric variables. Again
  469. there is much more to the subject of variables
  470. than we will cover here, but in their simplest
  471. form they are just letters or short names that
  472. can be assigned a value, and used to represent
  473. that value in calculations (just as you would
  474. do in algebra, remember that?).
  475. Any text string or number that is used
  476. explicitly rather than assigned to a variable
  477. is a constant.
  478. As well as being useful and flexible tools for
  479. use in calculations, variables have the useful
  480. facility that they can be given descriptive
  481. names such as profit and sales which make it
  482. very much easier to follow the logic of the
  483. computer listing to see what each line is
  484. doing.
  485. So valuable is this feature that MaxonBASIC
  486. also allows constants to be given descriptive
  487. names as well. To denote that a given name is
  488. to be treated as a constant and not a variable
  489. we must use the keyword CONST.
  490. Try this example:
  491.  
  492.  
  493. CONST costs% = 1500
  494. sales = 2000
  495.  
  496. REM Profit is simply sales less costs
  497. profit = sales-costs%
  498. PRINT "The expected profit will be"
  499. PRINT profit
  500.                        
  501.                        
  502. As a simple illustration of the usefulness of
  503. variables edit the first two lines of the
  504. program to give different values for costs% and
  505. sales; do this by placing the cursor at the end
  506. of the first line, pressing Backspace to delete
  507. the 1500 and entering another value. Repeat
  508. this for sales. Run the program and then close
  509. the window.
  510. Later in this tutorial we will see that the
  511. program can be extended to automatically ask
  512. you for values for these variables as the
  513. program is run.
  514. Variables can also be defined that hold text
  515. rather than a number. To warn BASIC that this
  516. is what you intend to do, syntax demands that
  517. all text variable names must end in the $
  518. character. In computer speak ´$´ is often
  519. pronounced ´string´ and represents ´a string of
  520. letters joined together´. The text that you
  521. wish to enter into the variable must again be
  522. enclosed in quotes.
  523.  
  524. An example is:
  525.  
  526.  
  527.  
  528. name$ = "High Quality Software"
  529. PRINT "HiSoft means ";
  530. PRINT name$
  531.  
  532.  
  533. Now run your program.
  534. You may have noticed something different about
  535. the way that the above program produced its
  536. output i.e. it is all contained on one line.
  537. This is the result of the semi-colon (´;´) at
  538. the end of the second line.
  539. The semi-colon is one of many possible ways we
  540. can control the way that PRINT statements are
  541. displayed, and these will be detailed later.
  542. For the time being though it is useful to know
  543. that the semi-colon ensures that any following
  544. print statement is added onto the end of the
  545. existing one, rather than starting a completely
  546. new line. We will be using this feature a lot
  547. when we start to look at programs that would
  548. otherwise very quickly fill the screen with
  549. information. Notice also the trailing space at
  550. the end of the second line - we need this to
  551. avoid running the words means and High
  552. together.
  553. The above programs are useful illustrations of
  554. how variables work, but they do not really
  555. reflect the way that we use them in real
  556. programs. The truth is that we often do not
  557. know in advance what the value of a variable is
  558. to be before the program is run. It is
  559. possible, as above, to edit the list of
  560. variables and recompile the program every time
  561. we use it, but a much more powerful and
  562. flexible method is of course to get the
  563. computer to ask you for the variable´s current
  564. value whilst the program is running. This is
  565. done using the INPUT keyword.
  566. If you use the keyword INPUT followed by a
  567. variable name, the computer will display a
  568. question mark on the screen and pause the
  569. program until it has had an answer from you, as
  570. in this example:
  571.  
  572.  
  573. INPUT x
  574. y = x * 10
  575. PRINT "Ten times"; x ; "equals"; y
  576.  
  577.  
  578. Of course, in a long and complex program we
  579. will want to be much more friendly than that -
  580. question marks appearing at random to request
  581. unspecified information can be rather
  582. confusing!
  583. The INPUT statement therefore allows you to
  584. enter a explanatory line of text that will be
  585. displayed together with the question mark.
  586.  
  587. INPUT "What is this year´s profit "; x
  588. There are of course very many other simple
  589. BASIC commands that each achieve a certain
  590. effect. There really is no point in detailing
  591. each of them here, but look through the Command
  592. Reference section and find some more to try.
  593. Unless you are very unlucky with your choice,
  594. absolutely no harm can be done, but it is just
  595. as well to avoid using the commands BLOAD, PEEK
  596. and POKE for the time being.
  597. Here is an example of how to read the syntax of
  598. each command so that you know what MaxonBASIC
  599. expects.
  600.  
  601.  
  602.  
  603. Reading the Syntax
  604.  
  605.  
  606. INPUT ["prompt"{;|,}] variable_list
  607. First of all, INPUT is the actual command and
  608. must be present to achieve anything at all.
  609.  
  610. ["prompt"{;|,}]
  611. The square brackets ([]) around the whole entry
  612. indicate that its use is optional, you can
  613. leave it out and the syntax will still be
  614. valid. If you choose to use it though, you must
  615. enclose a message in double quotes ("") and
  616. finish the message with either a semi-colon or
  617. a comma. The curly brackets ({}) denote a
  618. choice with the vertical bar (|) separating the
  619. choices that are available in this case. In
  620. fact, using the semi-colon to end the prompt
  621. string adds a question mark to the end of the
  622. string, while using the comma will not add
  623. anything to the string.
  624.  
  625. variable_list
  626. Finally, the INPUT statement must be finished
  627. with a list of variable names to which you want
  628. to assign data - this is not optional.
  629. With just these few commands that we have
  630. already learnt we can go a long way towards
  631. writing programs that show the real power of
  632. BASIC and in particular the way computers can
  633. handle repetitive and logical tasks with ease.
  634.  
  635.  
  636. The Heart of a BASIC Program
  637.  
  638. Individual keywords can be strung together to
  639. make up quite long and complex commands. These
  640. make up the mechanics of your program. However
  641. over and above these the essence of most
  642. computer software lies in certain programming
  643. techniques that bring these commands to life,
  644. and structure them together in an intelligent
  645. and flexible way.
  646. There are really three very simple concepts
  647. that lie at the heart of every BASIC program.
  648. Once these are understood, learning how any
  649. program works will just be a matter of studying
  650. the small details.
  651. The three concepts are repetition, logical
  652. tests & decision making and passing control.
  653.  
  654.  
  655. Repetition - Loops
  656.  
  657. Computers have certain strengths that make them
  658. powerful and extremely flexible tools. In some
  659. ways they are also rather stupid; they have to
  660. be told everything that they are expected to
  661. do. On the other hand they are able to perform
  662. these required tasks with great speed and, at
  663. least in theory, they will be able to repeat
  664. them ad infinitum without ever getting bored
  665. and making a mistake.
  666. One of the most important types of command we
  667. have available in most computer languages is
  668. known as a loop. This is the means by which we
  669. can make sure that commands can be repeated as
  670. many times as necessary without having to type
  671. them in over and over again.
  672. The most common type of loop seen in BASIC
  673. programs is the FORÉNEXT statement. This works
  674. by letting you set up a simple numeric variable
  675. as a counter which controls the number of times
  676. the following instructions are to be repeated.
  677. The NEXT command signals the end of the loop
  678. and tells the computer to move the counter onto
  679. its next value. This is what it can look like
  680. in practice:
  681.  
  682.  
  683. FOR x = 1 TO 6
  684.  PRINT "Hello"
  685. NEXT x
  686. The result will be:
  687.  
  688. Hello
  689. Hello
  690. Hello
  691. Hello
  692. Hello
  693. Hello
  694.  
  695.  
  696. Try it out.
  697. You can also specify the size of the jumps that
  698. the counter makes. Edit the first line to read:
  699.  
  700.  
  701. FOR x = 1 TO 6 STEP 5
  702.  
  703.  
  704. Do this by placing the cursor at the end of the
  705. first line and typing STEP 5.
  706. You should then see the results:
  707.  
  708.  
  709. Hello
  710. Hello
  711.  
  712.  
  713. The counter values can of course be set by
  714. other variables. Consider this short program:
  715.  
  716.  
  717. CONST start% = 4, finish% = 12
  718. jump = 2
  719. FOR x=start% TO finish% STEP jump
  720.  PRINT x
  721. NEXT x
  722.  
  723.  
  724. We have introduced CONST to define one or more
  725. constant values and to give them names. This is
  726. very useful for writing easy-to-understand
  727. programs and you are encouraged to use CONST
  728. whenever you have values that will not change
  729. over the life of your program. Once defined,
  730. you cannot change the value of a named
  731. constant.
  732. One particularly useful feature of the FOR loop
  733. is that we can run one loop inside another
  734. using the technique known as nesting.
  735.                        
  736. The second loop runs through in its entirety
  737. every time the first loop executes just one
  738. step. Note that we have used indentation (i.e.
  739. adding spaces or tabs at the beginning of the
  740. line) to make the logic of the program more
  741. obvious. It is good programming practice to use
  742. indentation for statements within loops.
  743. In fact MaxonBASIC allows you to omit the
  744. variable name in the NEXT statement as in:
  745.  
  746.  
  747. FOR x = 1 TO 10
  748.  PRINT x
  749. NEXT
  750.  
  751.  
  752. In this case the computer understands that you
  753. are referring to the counter variable x.
  754. Wherever an unspecified NEXT statement is
  755. found, the compiler will assume that it belongs
  756. to the last FOR in the listing.
  757. However, we do not advocate this omission of
  758. variable names with NEXT as it can cause
  759. unnecessary confusion and bugs.
  760. Loops are very useful things; they allow you to
  761. use the power of the language to automate all
  762. sorts of tedious tasks and achieve remarkable
  763. effects.
  764. If that was all there was to programming, our
  765. programs would be very mundane and predictable,
  766. doing essentially the very same tasks every
  767. time they were run. To make software more
  768. sophisticated and useful we have to introduce
  769. something else, the element of choice. Programs
  770. must be able to make decisions based on the
  771. information they have been presented with, ask
  772. the user what they are to do next and act on
  773. the reply. They must then produce different
  774. output in response to the value of certain
  775. variables.
  776.  
  777.  
  778. Decision Making
  779.  
  780. Almost every program you write will use the
  781. ability of the computer to rapidly and
  782. repeatedly make logical tests and decide upon
  783. what action it should do next based on the
  784. results. A word processor decides whether to
  785. delete a word or insert a letter based on a
  786. test of what keys are being pressed; a space
  787. invaders game decides whether to ´fire a
  788. missile´ based on what is happening to the
  789. joystick - it knows whether to blow up an alien
  790. based on a test of the relative position of
  791. this missile on the screen and so on.
  792. There are two main statements that are used to
  793. make logical tests within BASIC. These are:
  794.  
  795. IFÉTHENÉELSE and SELECT CASE.
  796.  
  797. IFÉTHENÉELSE statements are virtually self-
  798. explanatory. They take the following form:
  799.  
  800. IF something is true THEN
  801.   do this
  802. ELSE
  803.   do this instead
  804. END IF
  805.  
  806. This really is no different to any (logical)
  807. decision we make in everyday life - the
  808. computer is just making its own assessment of
  809. the current state of affairs and then deciding
  810. which instructions to follow subsequently.
  811. The END IF command may be unfamiliar to people
  812. who have used older versions of BASIC.
  813. MaxonBASIC allows each set of instructions
  814. following the various parts of the structure
  815. (IF, THEN and ELSE) to cover several lines of
  816. the listing. END IF (note the space between END
  817. and IF) is therefore necessary to signal when
  818. all of the commands associated with the
  819. IFÉTHENÉELSE statement have finished, and where
  820. the remainder of the program is to continue.
  821. It is possible to omit the ELSE part of this
  822. structure, which is useful when you want the
  823. program to do something if a certain condition
  824. is true, but to carry on as normal otherwise.
  825. IFÉTHEN statements can be nested within one
  826. another to increase the range of choices using
  827. the keyword ELSEIF e.g.
  828.  
  829. IF condition one is true THEN
  830.   do instruction one
  831.   ELSEIF condition two is true THEN
  832.     do instruction two
  833.   ELSEIF condition three is true THEN
  834.     do instruction three
  835.   ELSE do instruction four
  836. END IF
  837.  
  838. As you can imagine it can get rather
  839. complicated for you to follow the argument and
  840. feel confident that the logic used really is
  841. correct but clear use of indentation helps
  842. greatly. Examples of IF statements follow
  843. shortly.
  844. A structure that can often be used as an
  845. alternative to IF is the SELECT CASE structure
  846. which is ideal for allowing the computer to
  847. make one from a very wide selection of choices
  848. depending on the results of the logical test it
  849. has made. Although the exact syntax of the
  850. command when you use it will be rather
  851. different, you can think of SELECT CASE as
  852. representing a situation like (in plain
  853. English):
  854.  
  855. SELECT from the following
  856.   In the CASE where this test is true
  857.      do this
  858.   In the CASE where the this test is true
  859.      do this instead
  860.   In the CASE where this test is true
  861.      do something completely different
  862.   In the CASE where something ELSE is true
  863.      do this
  864. END SELECT
  865.  
  866. (The END SELECT command is essential to let the
  867. computer know that it has reached the end of
  868. the instructions relating to the last CASE).
  869. Before we can go on and give working examples
  870. of these commands and their correct syntax, it
  871. is important to illustrate exactly how the
  872. computer can go about making logical tests.
  873.  
  874. Logical Tests
  875. Computer logic resolves all things down to a
  876. simple test of ´true´ or ´false´. These two
  877. possible conditions can be made to represent
  878. almost everything you wish, from whether a
  879. switch is on or off to whether your bank
  880. account is in the black or in the red but, in
  881. the end, all the computer cares about is
  882. whether the test you have requested results in
  883. a ´true´ or a ´false´ result.
  884. BASIC uses the values of 0 for FALSE and -1 for
  885. TRUE. Why this is so would take an explanation
  886. of how BASIC calculates, and how it holds
  887. numbers in memory. We will be tackling these
  888. issues in more depth later but if you are ready
  889. for them now you have opened the manual at the
  890. wrong page.
  891. The main point for beginners to bear in mind is
  892. that, while the correct explanation of how
  893. computer logic works sounds both confusing and
  894. highly unlikely, in practice using it is a
  895. remarkably simple and obvious process.
  896. The use of logical tests in BASIC hinges around
  897. the following conditional symbols, known as
  898. relational operators, which express the
  899. criteria by which the computer is to determine
  900. whether the test is ´true´ or not.
  901.  
  902.  
  903.  
  904. >       greater than
  905. <       less than
  906. =       equal to
  907. <>      not equal to
  908. >=      greater than or
  909.         equal to
  910. <=      less than or
  911.         equal to
  912. ==      almost equal to
  913.   
  914.   
  915.   
  916.   The  last  option,  ==,  will  come  as  a
  917.   surprise  to anyone used to other versions
  918.   of  the  language. It is used is to  allow
  919.   text    comparisons   that   ignore    any
  920.   differences  in  the  case  of   the   two
  921.   strings,  and to allow comparison  between
  922.   two floating point numbers - which will be
  923.   explained later - to ensure that  a  match
  924.   is  made  despite  small  rounding  errors
  925.   during calculation.
  926. It doesn´t take a genius to figure out that the
  927. comparisons these make must be between two
  928. variables, or a variable and a constant -
  929. testing between two constants is pointless as
  930. it will give the same result every time
  931. (although this is occasionally useful to force
  932. a result).
  933. We can now look at a typical IFÉTHEN statement
  934. - Close your existing source code window and
  935. type this in:
  936.  
  937.  
  938. INPUT "What is your income this year"; income
  939. INPUT "What will be your costs"; costs
  940. IF income > costs THEN
  941.  PRINT "Hooray!"
  942.  PRINT "We´re in the money!"
  943. ELSE
  944.  PRINT "Start packing your bags!"
  945.  PRINT "I´ll book the boat to South America."
  946. END IF
  947.  
  948.  
  949. Providing different values for the income and
  950. costs will show exactly how the computer´s
  951. output reflects the result of the test. Try
  952. putting a FORÉNEXT loop round the outside of
  953. the program to try out 5 different sets of
  954. income/cost ratios.
  955. Note that, if you use multi-line IF statements,
  956. the IF, ELSE and END IF must be on lines by
  957. themselves.
  958. Here is an example using a SELECT CASE
  959. statement to show one version of the correct
  960. syntax. To maintain compatibility with as many
  961. versions of BASIC as possible this command
  962. structure has been implemented in a very
  963. flexible way and you are referred to the
  964. Command Reference section for a full list of
  965. the options.
  966.  
  967.  
  968. INPUT "A number, please";a
  969. SELECT CASE a
  970.  CASE = 12
  971.      PRINT "Number = 12"
  972.  CASE > 20
  973.      PRINT "Number is greater then twenty"
  974.  CASE <= 4
  975.      PRINT "Number is 4 or less"
  976.  CASE ELSE
  977.      PRINT "Number hasn´t met any of my
  978. conditions"
  979. END SELECT
  980.  
  981.  
  982. To extend the usefulness of the above
  983. relational operators we have the keywords AND,
  984. OR, XOR, EQV and IMP. These are used to compare
  985. two separate tests and to make judgements about
  986. their relative validity.
  987. The first two are again very easy to grasp as
  988. in the following examples:
  989.  
  990.  
  991. IF income > costs AND tax < profit THEN
  992.  PRINT "Hooray!"
  993. END IF
  994.  
  995.  
  996. The expression will only evaluate as ´true´ if
  997. both conditional tests are themselves true.
  998.  
  999.  
  1000. IF income > costs OR tax_rebate > 5000 THEN
  1001.  PRINT "Hooray!"
  1002. END IF
  1003.  
  1004.  
  1005. The expression in line 1 will evaluate as
  1006. ´true´ if one or other or both of the tests are
  1007. themselves true.
  1008. XOR is a trickier one to define as it has no
  1009. direct comparison in the English language. It
  1010. essentially stands for eXclusive-OR which means
  1011. that the expression will evaluate as true if
  1012. one or the other half is itself true but not if
  1013. they are both true together e.g.
  1014.  
  1015.  
  1016. IF income > costs XOR deficit < max_tax_loss
  1017. THEN
  1018.  PRINT "Hooray!"
  1019. END IF
  1020.  
  1021.  
  1022. EQV, short for EQuiValent, is used when two
  1023. tests are to be made which need to give the
  1024. same result, whether the result is true or
  1025. false i.e.
  1026.  
  1027.  
  1028. x = 1 : y=2
  1029. IF x = 10 EQV y = 230 THEN PRINT "Yep"
  1030.  
  1031.  
  1032. will print Yep because both comparisons give an
  1033. equivalent result i.e. ´false´.
  1034. IMP stands for ´is IMPlied by´ This is without
  1035. question the most abstract of the logical
  1036. tests. To complicate matters even further it is
  1037. the only logical operator that puts a strong
  1038. emphasis on the order in which the two subtests
  1039. are listed. It can best be understood as a
  1040. measure of whether or not the result of the
  1041. second test can be implied by, or concluded
  1042. from, the result of the first test.
  1043. The rules are that:
  1044. ¥  a  TRUE  result  can  be  concluded  from  a
  1045.  preceding TRUE result;
  1046. ¥  a  FALSE  result  can be  concluded  from  a
  1047.  preceding FALSE result;
  1048. ¥  a  FALSE  result  can be  concluded  from  a
  1049.  preceding TRUE result;
  1050. ¥  a  TRUE  result cannot be concluded  from  a
  1051.  preceding FALSE result.
  1052. The premise is that it is possible to draw the
  1053. wrong conclusions from correct assumptions, but
  1054. it is impossible to draw the correct
  1055. conclusions from wrong assumptions - try these
  1056. out:
  1057.  
  1058.  
  1059. x = 1 : y = 2
  1060.  
  1061. IF x<2 IMP y<3 THEN PRINT "Yep" ELSE PRINT "No"
  1062.  
  1063. IF x=2 IMP y=10 THEN PRINT "Yep" ELSE PRINT
  1064. "No"
  1065.  
  1066. IF x=1 IMP y=10 THEN PRINT "Yep" ELSE PRINT
  1067. "No"
  1068.  
  1069. IF x=2 IMP y=2 THEN PRINT "Yep" ELSE PRINT "No"
  1070.  
  1071.  
  1072. The implications of all the above logical
  1073. operators can be reversed by the use of the
  1074. keyword NOT as in:
  1075.  
  1076.  
  1077. IF NOT (x=10 AND y=12)
  1078.  
  1079.  
  1080. and so on.
  1081.  
  1082. Testing Text
  1083. It is of course equally possible to make
  1084. logical tests on text data. The relational
  1085. operators we use to express the test are the
  1086. same as with the numeric examples given above
  1087. but the way in which the computer evaluates
  1088. whether the result is TRUE or FALSE is rather
  1089. more complex.
  1090. Possibly the simplest to start with is to test
  1091. whether two text strings are equal (=) or not
  1092. equal (<>). Obviously this example:
  1093.  
  1094.  
  1095. test$ = "FRED"
  1096. IF test$ <> "BILL" THEN BEEP
  1097.  
  1098.  
  1099. is straightforward.
  1100. But what about operators such as greater than
  1101. (>) or less than (<)? How can we say that one
  1102. word or letter is ´greater´ than another?
  1103. To understand the answer we will have to make a
  1104. diversion into looking at the way computers
  1105. store letters in their memory.
  1106. Despite the way they look on screen, computers
  1107. store letters in their memory as numbers. All
  1108. modern computers stick to an American
  1109. convention known as ASCII (which incidentally
  1110. stands for American Standard Code for
  1111. Information Interchange) whereby each letter
  1112. has a certain number associated with it. By
  1113. standardising things in this way it has made it
  1114. possible for computers to talk to each other
  1115. and send text such as Hello Jim without it
  1116. coming out as ghJJm KPhZz.
  1117. Note that all lower case letters have higher
  1118. numbers than all the upper case ones. The
  1119. digits (0-9) come before both. The letters with
  1120. a value of 0-31 in the ASCII table are special
  1121. control characters. Sending these, or a
  1122. combination of them, to the screen or printer
  1123. often produces a response such as changing some
  1124. characteristic of the display, or type style,
  1125. or moving the cursor.
  1126. In a logical test, the first character of each
  1127. of the two strings that are being compared will
  1128. be tested - if one has a higher ASCII number
  1129. than the other it will be regarded as
  1130. ´greater´. If both characters have the same
  1131. ASCII number the computer will move on to the
  1132. next character in both strings.
  1133. If both strings are the same for all of their
  1134. common length except that one is longer than
  1135. the other, the longer one will be regarded as
  1136. greater rather than the shorter string.
  1137. Note also that even a blank space is a
  1138. character and it comes before all others (value
  1139. 32 in the ASCII table). A leading space in some
  1140. of the data is a common way in which text
  1141. comparisons can become completely confused, and
  1142. it can be a very difficult problem to spot.
  1143. Perhaps it all sounds a little complex, but the
  1144. encouraging thing is that in practice it is
  1145. easier than it looks. Common sense will usually
  1146. tell you what the outcome of any test between
  1147. two strings will be. The only time it is likely
  1148. to be as clear as mud is when punctuation and
  1149. unusual characters such as †, ¯, and § are
  1150. compared, as these tend to occur in
  1151. unpredictable places in the standard ASCII
  1152. character set.
  1153. The relational operator == is particularly
  1154. valuable when making text comparisons, as it
  1155. can be used to ignore any differences between
  1156. the case of the letters being compared e.g.
  1157.  
  1158.  
  1159. INPUT "Are you happy"; ans$
  1160. IF ans$=="Yes" THEN PRINT "I´m glad!"
  1161.  
  1162.  
  1163. Will give a glad message if you respond with
  1164. YES, yes, Yes etc. but not if you answer No.
  1165.  
  1166.  
  1167. Logical Loops
  1168.  
  1169. We have so far seen how to get the computer to
  1170. execute a series of instructions a set number
  1171. of times as a loop. We have also seen how to
  1172. make it decide, from a series of options, what
  1173. it is to do next, based on a logical test.
  1174. The situation often arises where the user
  1175. simply cannot predict how many times a certain
  1176. loop will be required to execute and it would
  1177. be ideal if we could get the computer to use
  1178. its logic to decide this for itself whilst
  1179. running. MaxonBASIC provides several methods of
  1180. doing just this, based on special loops that
  1181. continue to execute until a logical test tells
  1182. them to stop.
  1183. (Note that many inferior BASICs which lack
  1184. these facilities sometimes forced the user to
  1185. insert a logical test within a FORÉNEXT loop.
  1186. This test would force an unannounced jump from
  1187. within the loop and end its execution when the
  1188. true result was reached. Most authorities would
  1189. agree that this is bad programming practice
  1190. although it was often the best way of getting
  1191. the job done under the circumstances. Unlike
  1192. some languages, MaxonBASIC can handle such
  1193. ´jumps´ without complaint, but the programs you
  1194. write will be much clearer if you avoid doing
  1195. so and use the following structures.)
  1196. The three logical loops that we can use are
  1197. known as the WHILEÉWEND, REPEATÉEND REPEAT and
  1198. DOÉLOOP statements.
  1199. The first one works like this.
  1200.  
  1201. The WHILE loop
  1202.  
  1203. WHILE conditional test is true
  1204.     do this
  1205.     do this
  1206. WEND
  1207.  
  1208. The WEND keyword simply signals the end of the
  1209. instructions that are to be included within the
  1210. loop.
  1211. Here is an example:
  1212.  
  1213.  
  1214. INPUT "What is your bank balance"; balance
  1215. income = 50
  1216. month = 1
  1217. WHILE (balance>0) AND (income>49)
  1218.  PRINT "What is the income for month"; month;
  1219.  INPUT income
  1220.  PRINT "What are the costs for month"; month;
  1221.  INPUT costs
  1222.  balance = balance + (income - costs)
  1223.  PRINT "New balance is"; balance
  1224.  month = month + 1
  1225. WEND
  1226. PRINT "It´s time to look at getting a proper
  1227. job!"
  1228.  
  1229.  
  1230. Note that, in order to ensure that the WHILE
  1231. loop is executed at least once, we have had to
  1232. initialise income to 50 (>49) before the
  1233. beginning of the loop.
  1234. In fact, it would be better, therefore, to use
  1235. a different type of loop, the DO loop, for this
  1236. example and we shall now see why.
  1237.  
  1238. The DO loop
  1239. The DO loop actually has several permutations
  1240. which make it a very much more flexible
  1241. construction than the WHILE loop. In fact it
  1242. even has an option that will completely
  1243. simulate the WHILEÉWEND command. The various
  1244. permutations include:
  1245.  
  1246. DO
  1247.     this instruction
  1248.     that instruction
  1249. LOOP UNTIL condition
  1250. DO UNTIL condition
  1251.     this instruction
  1252.     that instruction
  1253. LOOP
  1254.  
  1255. Can you see that these constructs are similar
  1256. to a WHILE loop? Are there any differences?
  1257. Yes É a DO UNTILÉLOOP executes the instructions
  1258. in the loop until the condition becomes true
  1259. whereas a WHILE loop executes until the
  1260. condition becomes false. Also DOÉLOOP UNTIL
  1261. checks its exit condition at the end of the
  1262. loop, not at the beginning. Thus, in the
  1263. previous example, since we did not know the
  1264. value of income at the start of the loop,
  1265. perhaps we should have used a DOÉLOOP UNTIL
  1266. loop, not a WHILE loop - can you re-write it?
  1267. There are other permutations of DO:
  1268.  
  1269. DO WHILE condition
  1270.     this instruction
  1271.     that instruction
  1272. LOOP
  1273. DO
  1274.     this instruction
  1275.     that instruction
  1276. LOOP WHILE condition
  1277.  
  1278. As we said above, the logic of the WHILE
  1279. comparison is opposite to that of the UNTIL
  1280. option:
  1281.  
  1282.  
  1283. DO UNTIL x = 10
  1284. and
  1285.  
  1286. DO WHILE x <> 10
  1287.  
  1288.  
  1289. will produce exactly the same effect.
  1290. The most general form of the DO loop is:
  1291.  
  1292. DO
  1293.     this instruction
  1294.     that instruction
  1295. LOOP
  1296.  
  1297. This command structure will continue to run and
  1298. run unless there is a logical test inserted
  1299. somewhere within it terminating in an EXIT DO
  1300. or EXIT LOOP command; these two are
  1301. interchangeable.
  1302. It is again possible to nest such loops several
  1303. times, and indeed to nest one type inside
  1304. another.
  1305. It is also possible to have conditional tests
  1306. at both ends of a DOÉLOOP.
  1307.  
  1308. The REPEAT loop
  1309. The third type of logical loop is the
  1310. REPEATÉEND REPEAT structure. This has the most
  1311. in common with the final form of the DOÉLOOP
  1312. that we have just seen, in that there is no
  1313. builtin way for the loop to terminate beyond
  1314. the inclusion of one or several EXIT
  1315. statements.
  1316. The difference between the two types of loop
  1317. hinges on the fact that each REPEAT loop you
  1318. create can be given its own name. Several such
  1319. loops can be nested culminating in a series of
  1320. logical tests with EXIT statements. Any EXIT
  1321. statement can itself refer to the name of a
  1322. given loop, but not necessarily the one that
  1323. was most recently defined. In other words you
  1324. can EXIT a named outer loop from within an
  1325. inner one; very useful for aborting some task
  1326. if a catastrophic error occurs.
  1327. We advise the use of DOÉLOOPs wherever possible
  1328. since they have a much more coherent structure
  1329. - try to avoid REPEAT loops unless absolutely
  1330. necessary.
  1331.  
  1332.  
  1333. Passing Control Within a Program
  1334.  
  1335. The effect of logical tests is to force the
  1336. program to make a decision about which lines of
  1337. the program are to be executed next. In other
  1338. words the flow of the program is passed from
  1339. one section to another.
  1340. Most large programs contain sections that are
  1341. only executed as and when certain conditions
  1342. are met. A space invaders game for example will
  1343. have a GAME OVER message that will only be
  1344. displayed when the program has realised that
  1345. you have had all of your missile bases
  1346. destroyed. As long as you can continue playing
  1347. unscathed, control of the computer will never
  1348. pass to the end-game section of the program.
  1349. In the above examples the logical tests have
  1350. passed control to one or two lines of the
  1351. program, for very simple results. However there
  1352. is no reason why there should not be enormously
  1353. long and complex sections of the program that
  1354. are accessed in each case.
  1355. There are two distinct mechanisms that we can
  1356. use to cause the computer to move to another
  1357. section of the program. These are jumps and
  1358. subroutine calls. The difference between the
  1359. two is that when the computer jumps to a
  1360. different part of the program it does not
  1361. bother to remember where it came from and it is
  1362. not able, and does not try, to get back there
  1363. unless you explicitly tell it where to go. By
  1364. contrast, subroutines and sub-programs are self
  1365. contained sections of the program that fulfil a
  1366. specific task and then automatically return
  1367. back to the next instruction following the one
  1368. that first called them.
  1369. In older versions of BASIC, versions that
  1370. required the user to begin each line with a
  1371. number, jumps were made by simply entering GOTO
  1372. line numbers as in the following example.
  1373.  
  1374.  
  1375. 10 LET x = 1
  1376. 20 LET y = 20
  1377. 30 LET x = x + 1
  1378. 40 IF x = y THEN BEEP ELSE GOTO 30
  1379.  
  1380.  
  1381. This example also shows how very primitive
  1382. logical loops can be created - the program will
  1383. jump between lines 30 and 40 until the test is
  1384. passed as true.
  1385. Although it is capable of running the above
  1386. program, MaxonBASIC does not force the
  1387. programmer to use line numbers. But in that
  1388. case how would we signal to the program when it
  1389. is to make a jump, and where it is expected to
  1390. go to?
  1391. The answer is through the use of line labels,
  1392. which are essentially names that we give to
  1393. chosen lines in the program, usually lines that
  1394. start a certain routine. By making a jump to
  1395. one of these names the same effect is achieved
  1396. as with a line number jump but the listing is
  1397. made much more readable. Line labels are
  1398. entered by just typing the required name
  1399. followed by a colon.
  1400.  
  1401.  
  1402. maingame:
  1403.  .
  1404.  
  1405.  .
  1406. IF missile_base = 0 THEN GOTO endgame
  1407.  .
  1408.  .
  1409. endgame:
  1410. BEEP
  1411. PRINT "Game over."
  1412.  
  1413.  
  1414. In older versions of BASIC, subroutines were
  1415. similarly accessed by a call to a certain line
  1416. number which was to be the beginning of the
  1417. routine itself. The keyword that makes this
  1418. call is GOSUB. Here is an example:
  1419.  
  1420.  
  1421. 10 INPUT "What is your bank balance"; x
  1422. 20 IF x >0 THEN GOSUB 100 ELSE GOSUB 200
  1423. 30 INPUT "How much will your bills be this
  1424. week"; z
  1425. 40 IF z > x THEN GOSUB 200
  1426. É
  1427. 100 BEEP
  1428. 110 PRINT "There will be no bank charges"
  1429. 120 RETURN
  1430. É
  1431. 200 BEEP
  1432. 210 PRINT "There will be bank charges"
  1433. 220 PRINT "unless you pay some money in"
  1434. 230 INPUT "How much can you pay in"; y
  1435. 240 IF y < x THEN PRINT "Not enough I´m afraid"
  1436. 250 END IF
  1437. 260 LET x=x+y
  1438. 270 RETURN
  1439.  
  1440.  
  1441. The keyword RETURN is essential to signal the
  1442. end of the current subroutine, otherwise the
  1443. subroutine would carry on ad infinitum.
  1444. The above example appears slightly laboured
  1445. because in very short programs it can be
  1446. difficult to justify the use of subroutines as
  1447. separate entities from the main lines of the
  1448. listing. In long and complex programs however
  1449. they perform several invaluable roles.
  1450. Firstly they allow the programmer to divide up
  1451. his work into a series of logical modules, each
  1452. one of which can be worked on, altered, tested
  1453. and debugged in isolation. As well as making
  1454. things easier for the author of the program,
  1455. they also make the listing very much easier to
  1456. follow and alter at a later date.
  1457. As an extension of this philosophy, once a
  1458. subroutine has been perfected it can be made
  1459. part of a stored ´source library´ of routines
  1460. which can, at any stage, be slotted into new
  1461. programs that are under development. For
  1462. example there may be a subroutine that plays a
  1463. tune which you can use in any game you write,
  1464. or you may have some lines which place a menu
  1465. of options on a screen, or which reads data
  1466. from a disk file.
  1467. Another important use for them is to make the
  1468. actual listing of your programs more compact
  1469. and economical. Any program routines that are
  1470. used several times within the same listing need
  1471. only be typed once, and they can then be
  1472. accessed by the appropriate subroutine call as
  1473. often as necessary.
  1474. MaxonBASIC will of course allow the use of
  1475. simple subroutines as described above but in
  1476. addition, as with GOTO, it is possible for the
  1477. routine to be called by a name rather than by
  1478. its line number, which of course makes the
  1479. listing easier to follow.
  1480. Avoiding numbers also makes it logistically
  1481. simpler to merge many different library
  1482. procedures together into a new program.
  1483. Another improvement is that the RETURN command
  1484. can be followed by a line number or label that
  1485. will allow the program flow to be passed to yet
  1486. another part of the listing.
  1487.  
  1488.  
  1489. A Better Way; Sub-programs
  1490.  
  1491. As well as standard subroutines, there is a
  1492. much more satisfactory way of organising
  1493. programs into modules which are called sub-
  1494. programs.
  1495. Sub-programs have three advantages over
  1496. subroutines, which may not be appreciated by
  1497. many programming beginners but will become more
  1498. and more important as your skills increase
  1499. together with the complexity of your programs.
  1500. These are:
  1501. ¥   local variables
  1502. ¥   parameter passing
  1503. ¥   recursion
  1504. Each of these will be explained as we progress
  1505. with the tutorial.
  1506. The keywords used for defining sub-programs are
  1507. SUB and END SUB. Once defined they can be
  1508. CALLed from anywhere else in your program
  1509. listing.
  1510. If you have been paying attention until now,
  1511. you should find it fairly easy to decipher the
  1512. following exampleÉ
  1513.  
  1514. Try typing this in and running it. It has
  1515. deficiencies; it only works properly using the
  1516. standard fonts; the sub-program should be
  1517. passed, as two parameters, the point at which
  1518. the text has been drawn and it should then work
  1519. out where to put the box É but you see the
  1520. idea.
  1521.                        
  1522.                        
  1523. Note the LOCATE x,y statement, after
  1524. Mainprogram:, which positions the cursor at row
  1525. x, column y within the window, so that the next
  1526. PRINT takes place there. The origin is 1,1 not
  1527. 0,0 as it is for graphics statements.
  1528. Here´s a chance to show off a useful feature of
  1529. the editor; you often want to use a sub-program
  1530. or a function in many different programs -
  1531. after all, that´s one of the main reasons for
  1532. coding them in the first place. You could group
  1533. all your sub-programs together in one program,
  1534. save it and ´include´ it in whichever program
  1535. was going to use the sub-program, function etc.
  1536. However, there is an easier way that you may
  1537. wish to use sometimes - simply cut the sub-
  1538. program from one window and paste it into
  1539. another, here´s how:
  1540. Position the cursor at the start of the REM
  1541. statement, click and hold the button down. Now
  1542. drag the mouse until you have marked all the
  1543. text up to the end of the END SUB and release
  1544. the mouse button.
  1545.                        
  1546.                        
  1547. Now select Copy from the Edit menu; this copies
  1548. the marked text into memory.
  1549.                        
  1550.                        
  1551. Now open a new window (AN) and select Paste
  1552. from the Edit menu. The complete sub-program is
  1553. copied into your new window, ready for use.
  1554. Back to sub-programs É
  1555. It is not uncommon to find well written modular
  1556. programs where the main body of the listing is
  1557. no more than a series of calls to different
  1558. subprograms as in the following:
  1559.  
  1560.  
  1561.  CALL start
  1562.  CALL input
  1563.  CALL output
  1564.  CALL end
  1565.  
  1566.  
  1567. You can invoke a sub-program called fred either
  1568. by using CALL fred or simply using the name of
  1569. the sub-program, fred. In this way routines can
  1570. be executed just by using their names, almost
  1571. as if they were special BASIC keywords that you
  1572. have written yourself. The Command Reference
  1573. section gives more details. However, we would
  1574. like to stress one point here:
  1575.  
  1576. CALL fred (john) is not the same as fred (john)
  1577.  
  1578. When using CALL, you must enclose the
  1579. parameters within parentheses and they are then
  1580. passed as variable parameters (see below).
  1581. However, when not using CALL, enclosing
  1582. parameters in parentheses forces the parameters
  1583. to be passed by value. Don´t blame HiSoft. It´s
  1584. historical!
  1585. More of sub-programs later.
  1586.  
  1587.  
  1588. Choosing where to go
  1589.  
  1590. A useful command structure that allows us to
  1591. program jumps to different routines in a very
  1592. concise way is ON x GOTO/GOSUB. In this case x
  1593. is a numeric variable that can contain a number
  1594. generated by the program, or entered by the
  1595. user. The command sequence tests the value of x
  1596. (or rather the integer value of x - see later)
  1597. and will jump to the xth entry in a list of
  1598. subroutine names, line labels or line numbers
  1599. that can follow the GOTO or GOSUB command. This
  1600. list can be up to 56 items long and can mix
  1601. line or subroutine names and numbers.
  1602.  
  1603.  
  1604. Mainprogram:
  1605. REM Other lines of the program
  1606.  
  1607. PRINT "Data listed on screen or printer?"
  1608. PRINT "Screen.......1"
  1609. PRINT "Printer......2"
  1610. DO
  1611.  BEEP
  1612.  INPUT answer
  1613. LOOP UNTIL (answer = 1) OR (answer = 2)
  1614.  
  1615. ON answer GOSUB screenprint, paperprint
  1616.  
  1617.  
  1618. Again the example looks like a rather
  1619. longwinded way to achieve a simple effect but
  1620. in complex programs this command structure is
  1621. invaluable. The chosen variable in your own
  1622. program can be used as an indicator (in
  1623. computer jargon: a flag) of what routines have
  1624. been accessed or what choices have been made by
  1625. the user and the program response tailored to
  1626. fit.
  1627. It is not possible to call sub-programs with
  1628. this command; to do this we recommend you use a
  1629. SELECT CASE structure with CALLs which would
  1630. look like:
  1631.  
  1632.  
  1633. Mainprogram:
  1634. REM Other lines of the program
  1635.  
  1636. PRINT "Data listed on screen or printer?"
  1637. PRINT "Screen.......1"
  1638. PRINT "Printer......2"
  1639.  
  1640. DO
  1641.  INPUT answer
  1642.  SELECT CASE answer
  1643.      CASE 1 : CALL screenprint
  1644.      CASE 2 : CALL paperprint
  1645.  CASE ELSE BEEP
  1646.  END SELECT
  1647. LOOP UNTIL (answer = 1) OR (answer = 2)
  1648.  
  1649.  
  1650. In general, we would advocate the use of CASE
  1651. over ON GOTO/GOSUB since it normally leads to
  1652. clearer programs.
  1653.  
  1654.  
  1655. Sub-programs
  1656.  
  1657. As we have said above, sub-programs are much
  1658. more powerful than old-fashioned subroutines
  1659. and we encourage you to use them whenever you
  1660. can.
  1661. Sub-programs have the ability to define and use
  1662. variables that are only valid within the
  1663. routine itself, but which have no effect on
  1664. other variables of the same name used elsewhere
  1665. in other routines or within the main program
  1666. body. These are what are known as local
  1667. variables, because they are only recognised and
  1668. used within one routine. They make it immensely
  1669. easier to write and test procedures as
  1670. independent modules without worrying about
  1671. compatibility with others that do different
  1672. tasks.
  1673. Say that we want to write a sub-program that
  1674. takes a text string and prints it ten times on
  1675. the screen. Our sub-program may be of the
  1676. following form:
  1677.  
  1678.  
  1679. SUB Mul_Print
  1680.  FOR x = 1 to 10
  1681.      PRINT A$
  1682.  NEXT x
  1683. END SUB
  1684.  
  1685.  
  1686. Do not try entering this routine just yet - we
  1687. will see shortly that it is not quite finished.
  1688. Firstly, note that we have introduced a
  1689. variable, x, that is used in the FORÉNEXT loop
  1690. as the loop counter - it is obviously only
  1691. needed while the loop is being executed and is
  1692. therefore a prime candidate for being a local
  1693. variable - we make it such by adding the
  1694. statement STATIC x after the SUB definition. We
  1695. have used the keyword STATIC to declare x as
  1696. local to this sub-program - it will not be
  1697. available outside the sub-program (but see
  1698. SHARED later).
  1699.   
  1700.   If   you  are  peachy-keen  you  may  have
  1701.   noticed  the keyword LOCAL in the Reserved
  1702.   Words  list  or the Command Reference  and
  1703.   you  may  be  wondering why  we  have  not
  1704.   declared  x  as  LOCAL.  This  is  because
  1705.   STATIC  x is more efficient on memory  and
  1706.   runs  faster  - LOCAL x introduces  a  new
  1707.   variable  every  time  it  is  encountered
  1708.   whereas STATIC x creates only one variable
  1709.   which  is re-used. The main occasion  when
  1710.   you  might  want to use LOCAL rather  than
  1711.   STATIC  is  if  you have a sub-program  or
  1712.   function  that calls itself and  you  need
  1713.   independent  local variables  within  each
  1714.   call.
  1715. Also, we have written the sub-program using the
  1716. text variable name of A$. However to satisfy
  1717. the requirements of flexibility and
  1718. independence from the main program variables we
  1719. have to find a way to tell the sub-program
  1720. exactly what A$ represents when we call it. The
  1721. situation may be that we may not have used that
  1722. variable name in the main program, or even that
  1723. we have used it for something completely
  1724. different.
  1725. Let´s write some code that might call
  1726. Mul_Print:
  1727.  
  1728.  
  1729. Main_Program:
  1730. A$ = "Banana"
  1731. B$ = "HiSoft = HIgh quality SOFTware"
  1732. PRINT "MENU"
  1733. PRINT "1. "; A$
  1734. PRINT "2. "; B$
  1735. INPUT x
  1736. SELECT CASE x
  1737.  CASE 1 :  choice$=A$
  1738.  CASE 2 :  choice$=B$
  1739.  CASE ELSE choice$="Not given"
  1740. END SELECT
  1741.  
  1742.  
  1743. The next thing we want to do in this program is
  1744. to make a call to the Mul_Print sub-program. We
  1745. need to let this sub-program know that we want
  1746. it to print choice$ rather than A$, even though
  1747. we have used the name A$ in the actual
  1748. Mul_Print routine. The SUB was possibly written
  1749. months before and stored in a library.
  1750. Our old type of subroutine detailed above will
  1751. have been unable to allow for this necessary
  1752. degree of flexibility. However when using sub-
  1753. programs we can do it with ease thanks to a
  1754. technique known as parameter passing.
  1755. To use this we first have to alter the first
  1756. line of our sub-program to contain not only the
  1757. name of the procedure, but also the parameters
  1758. it will expect to be given from the main
  1759. program.
  1760. In our example this would be:
  1761.  
  1762.  
  1763. SUB Mul_Print(A$)
  1764. STATIC x
  1765.  FOR x = 1 to 10
  1766.      PRINT A$
  1767.  NEXT x
  1768. END SUB
  1769.  
  1770.  
  1771. When we actually make the call to the sub-
  1772. program from the main program we have to also
  1773. include in that line the appropriate variables,
  1774. numbers or text strings that we want each
  1775. passed variable to represent.
  1776. In our example this line would be:
  1777.  
  1778. Mul_Print choice$
  1779. Not surprisingly the parameters that are passed
  1780. must match the parameters expected by the sub-
  1781. program in number, type and order but they need
  1782. not match with regard to the actual names used.
  1783. The complete program would be:
  1784.  
  1785.  
  1786. SUB Mul_Print(A$)
  1787. STATIC x
  1788.  FOR x = 1 to 10
  1789.      PRINT A$
  1790.  NEXT x
  1791. END SUB
  1792.  
  1793. Main_Program:
  1794. A$ = "Banana"
  1795. B$ = "HISOFT = HIgh quality SOFTware"
  1796. PRINT "Menu"
  1797. PRINT "1. "; A$
  1798. PRINT "2. "; B$
  1799. INPUT x
  1800. SELECT CASE x
  1801.  CASE 1
  1802.      choice$=A$
  1803.  CASE 2
  1804.      choice$=B$
  1805.  CASE ELSE choice$="Not given"
  1806. END SELECT
  1807. Mul_Print choice$
  1808.  
  1809.  
  1810. Not particularly useful, but it illustrates the
  1811. point. Note how the sub-program is defined
  1812. before the main program - this is good
  1813. programming practice, but not essential.
  1814. Now try editing the main program to include a
  1815. second option for choosing how many times the
  1816. string is to print. The Mul_Print sub-program
  1817. will have to have a second parameter entered
  1818. into the opening line, say Mul_Num which will
  1819. be used in the line:
  1820.  
  1821.  
  1822. For x = 1 to Mul_Num
  1823.  
  1824.  
  1825. Remember to put a second parameter in the call
  1826. to the sub-program to pass the value for this
  1827. variable that has been selected by the user.
  1828. By default MaxonBASIC assumes that all
  1829. variables that are declared or used by a sub-
  1830. program are STATIC variables i.e. are local to
  1831. the sub-program and will not affect or be
  1832. affected by the values of variables of the same
  1833. name elsewhere in your program. STATIC
  1834. variables are zeroed when your program is first
  1835. executed but are then left alone by MaxonBASIC
  1836. - their values are held static until you change
  1837. them within your program.
  1838. However, even though STATIC is the default, it
  1839. is advisable to explicitly declare any local
  1840. variables as STATIC (or LOCAL) since this
  1841. improves the readability and maintainability of
  1842. your program. Also, if you have variable checks
  1843. on (a compiler option), an error will be
  1844. reported if you use variables in a sub-program
  1845. or function that have not been declared.
  1846. However there are situations where it would be
  1847. valuable for the computer to create a new
  1848. variable each time a sub-program is called. If
  1849. you want MaxonBASIC to create a new variable
  1850. for each sub-program call then you should
  1851. declare the variable as LOCAL, not STATIC.
  1852.  
  1853. There is also a way of letting a sub-program
  1854. act on and even change the values of variables
  1855. that are used by the main program and without
  1856. these having to be passed to the subprogram as
  1857. parameters. We do this by stating, before they
  1858. are declared or used by the sub-program, that a
  1859. certain variable name is to be SHARED.
  1860. As you will be able to deduce from the example
  1861. programs we have used so far MaxonBASIC does
  1862. not force you to define exactly which variables
  1863. belong in which categories. The compiler is
  1864. able to deduce the effect that you are trying
  1865. to achieve unless there is a mistake in your
  1866. own logic. For that very reason it is good
  1867. programming practice to work out and specify
  1868. exactly which variables belong to which types
  1869. in your program.
  1870.  
  1871.  
  1872. SUB testproc
  1873. SHARED x,y
  1874.  PRINT x, y , z
  1875.  x = x + 10
  1876.  y = y + 10
  1877.  z = z + 10
  1878. END SUB
  1879.  
  1880. Mainprogram:
  1881.  x = 10 : y = 20 : z = 50
  1882.  PRINT x, y, z
  1883.  testproc
  1884.  PRINT x, y, z
  1885.  
  1886.  
  1887. This will produce the following output:
  1888.  
  1889.  
  1890. 10   20  50
  1891. 10   20  0
  1892. 20   30  50
  1893.  
  1894.  
  1895. which illustrates that x and y were usable, and
  1896. capable of being changed, by the sub-program
  1897. even though they were not passed as parameters.
  1898. The third variable, z, was in fact treated as
  1899. two entirely separate creatures because, by
  1900. default, it was STATIC to the sub-program. x
  1901. and y were created by, and belong to, the main
  1902. program unless SHARED; z belongs exclusively to
  1903. the sub-program.
  1904.   
  1905.   Remember,  the default situation  is  that
  1906.   every  variable  used in a sub-program  is
  1907.   regarded   as   STATIC  unless   specified
  1908.   otherwise. The use of variables  that  are
  1909.   SHARED  between sub-programs and the  main
  1910.   program  should  be treated  with  extreme
  1911.   caution  since  it  is easy  to  introduce
  1912.   obscure bugs using SHARED variables -  see
  1913.   the   SHARED  variables  section  in   the
  1914.   Concepts chapter for an example.
  1915. SHARED variables are not the only means by such
  1916. a sub-program can pass information or changes
  1917. back to the main program body and this brings
  1918. us on to a discussion about Value Parameters
  1919. and Variable Parameters.
  1920.  
  1921.  
  1922. Value and Variable Parameters
  1923.  
  1924. There are two different ways that you can pass
  1925. parameters to and from sub-programs with
  1926. MaxonBASIC; essentially you can either pass
  1927. just the value of the parameter to the sub-
  1928. program or you can pass a reference to the
  1929. parameter. In the latter case the parameter is
  1930. called a variable parameter because the sub-
  1931. program can actually modify the value of the
  1932. variable since it knows where to find it - all
  1933. parameters passed to sub-programs are, by
  1934. default, variable parameters. This provides
  1935. another mechanism, along with SHARED variables,
  1936. for sub-programs to communicate with the main
  1937. program and each other. For example:
  1938.  
  1939.  
  1940. SUB Strip_Spaces(a$)
  1941. STATIC b$,i,j
  1942. b$=""
  1943.  
  1944. REM Find first non-space character
  1945. i=0
  1946. DO
  1947.  i=i+1
  1948. LOOP UNTIL MID$(a$,i,1)<>" "
  1949.  
  1950. REM Now copy rest of string to temporary string
  1951. FOR j=i to LEN(a$)
  1952.  b$=b$+MID$(a$,j,1)
  1953. NEXT j
  1954.  
  1955. REM Copy back to passed string
  1956. a$=b$
  1957. END SUB
  1958.  
  1959. test$="    HiSoft"
  1960. Strip_Spaces test$
  1961. PRINT test$
  1962.  
  1963.  
  1964. Try this for yourself; it shows the use of a
  1965. variable parameter to strip the leading spaces
  1966. from a string variable. We have used a few
  1967. string functions (like MID$ and LEN$) that you
  1968. may not have seen before - don´t worry, they
  1969. will be explained later.
  1970.   
  1971.   In  fact,  there  is  a built-in  function
  1972.   called  LTRIM$  which will  strip  leading
  1973.   spaces   for   you  -  see   the   Command
  1974.   Reference.
  1975.  
  1976.   
  1977.   MaxonBASIC  allows  you  to  override  the
  1978.   default  that  a parameter is  a  variable
  1979.   parameter  - simply enclose the  parameter
  1980.   in  parentheses in the call  to  the  sub-
  1981.   program    e.g.    if    we    had    used
  1982.   Strip_Spaces(test$)  above,  test$   would
  1983.   have remained as HiSoft.
  1984.   
  1985.   If,  instead, you use CALL to  invoke  the
  1986.   sub-program  and  you want  the  parameter
  1987.   passed  by  value  when it  has  not  been
  1988.   declared   as   such  in  the  sub-program
  1989.   definition   then,  again,   enclose   the
  1990.   parameter in parentheses, for example:
  1991.   
  1992.   CALL Strip_Spaces ((test$))
  1993. The alternative to variable parameters is the
  1994. value parameter where only the value of the
  1995. variable is passed to the sub-program and the
  1996. variable itself cannot be modified. To indicate
  1997. that you want a variable to be passed by value,
  1998. you should precede it with the word BYVAL or
  1999. VAL in the sub-program definition.
  2000. For example:
  2001.  
  2002.  
  2003. CONST FALSE=0
  2004.  
  2005. SUB Factors(BYVAL Number)
  2006. STATIC i
  2007.  FOR i=2 TO Number/2
  2008.      IF Number MOD i=0 THEN PRINT i
  2009.  NEXT i
  2010. END SUB
  2011.  
  2012.  
  2013. DO
  2014. INPUT i
  2015. Factors i
  2016. LOOP UNTIL FALSE
  2017.  
  2018.  
  2019. There is no need to make Number a value
  2020. parameter in this example since it is not
  2021. modified within the sub-program - but value
  2022. parameters are processed considerably faster
  2023. than variable parameters and, in a calculation-
  2024. intensive (albeit simple) sub-program like this
  2025. one, speed can be of paramount importance.
  2026. So it is advisable to define your parameters as
  2027. value parameters unless you need them to be
  2028. otherwise.
  2029. Note also the use of CONST to define a constant
  2030. FALSE that can then be used with the DOÉLOOP to
  2031. loop forever. Type in this program and run it -
  2032. when you get bored hold down Ctrl-C to break
  2033. out of the program.
  2034. Now for a little funÉ
  2035.  
  2036.  
  2037. Recursion
  2038.  
  2039. Sub-programs do of course have the ability to
  2040. call other sub-programs in turn, or even to
  2041. call themselves if necessary. The level of
  2042. complexity of such inter-related calls can be
  2043. enormous, yet the resulting listing will remain
  2044. obvious and easy to follow because the
  2045. procedure name can almost be regarded as a
  2046. brand new keyword that does a certain job -
  2047. contrast that with a similar situation using
  2048. line numbers.
  2049. The ability of a sub-program to call itself is
  2050. known as recursion. This is an enormously
  2051. useful and powerful programming tool that opens
  2052. up whole new worlds of opportunity and in doing
  2053. so flies completely over the head of 90% of
  2054. computer users.
  2055. Unfortunately the programs used to demonstrate
  2056. the principle usually employ it to solve
  2057. complex and obscure mathematical problems that
  2058. are far from easy to follow. We are not
  2059. intending to let you off the hook either - on
  2060. the MaxonBASIC disk you will see a version of
  2061. the infamous ´Towers of Hanoi´ program, called
  2062. Hanoi.bas. This demonstrates the full power of
  2063. recursion by solving the sort of horrific mind
  2064. bending puzzle that most people cannot
  2065. visualise anyway and you should certainly study
  2066. it when you have finished working through this
  2067. book.
  2068. However, here is a procedure that demonstrates
  2069. recursion, at least to the extent of proving
  2070. that it really does work. Like many recursive
  2071. problems the same or a similar effect can be
  2072. achieved by the use of logical loops, but you
  2073. will often find that using procedures in this
  2074. way is often much more efficient in both speed
  2075. and compactness of your program.
  2076. Type this in:
  2077.  
  2078.  
  2079. ´ The ForWarD sub-program. Draws a line of
  2080. length
  2081. ´ r in the direction, dir, of the ´turtle´,
  2082. ´ from its current position
  2083. SUB FWD(BYVAL r)
  2084. SHARED curx, cury, dir
  2085. STATIC newx, newy
  2086. ´ Calculate the new x and y co-ordinates
  2087.  newx = curx + r * COS(dir)
  2088.  newy = cury + r * SIN(dir)
  2089. ´ Draw the line
  2090.  LINE (curx, cury) - (newx, newy)
  2091. ´ Update the (x, y) position of the turtle
  2092.  curx = newx
  2093.  cury = newy
  2094. END SUB
  2095.  
  2096. ´ Turn the turtle through r degress
  2097. ´ i.e. simply change dir
  2098. SUB RIGHT(BYVAL r)
  2099. SHARED dir
  2100.  dir = dir - r / 180 * 3.1415926
  2101. END SUB
  2102.  
  2103. ´ Use FWD and RIGHT to draw a spiral
  2104. ´ this sub-program is recursive, it calls
  2105. ´ itself to draw successive, longer lines
  2106. ´ to produce a spiral
  2107. SUB spirals(BYVAL L, BYVAL A)
  2108.  FWD L
  2109.  RIGHT A
  2110.  IF L < 150 THEN spirals L + 1, A
  2111. END SUB
  2112.  
  2113. ´ Initialise the turtle and draw a spiral
  2114.  
  2115. ´ You can try changing the numbers 9, 95 to
  2116. ´ obtain different shapes
  2117.  
  2118. main:
  2119.  curx = 160 : cury = 100 : dir = 0
  2120.  spirals 9, 95
  2121. END
  2122.  
  2123.  
  2124. Beginners may feel that they have been given a
  2125. fairly rough ride over the last few sub-
  2126. sections so let´s get back to some simpler
  2127. BASIC concepts for a while.
  2128.  
  2129.  
  2130. Functions
  2131.  
  2132. Functions are an extremely important group of
  2133. part of MaxonBASIC that encompass almost every
  2134. type of task you can wish your computer to do,
  2135. they can control graphics, text, calculation,
  2136. logic, indeed there are very few programs that
  2137. do not use functions of some sort in almost
  2138. every line. Any attempt to define what
  2139. functions do is therefore almost pointless -
  2140. they can do anything and everything.
  2141. What makes a function a function as distinct
  2142. from any other element of BASIC is that, once
  2143. called, it has to return some form of
  2144. information, text or numeric data, to the
  2145. original program. Most, but certainly not all,
  2146. functions need some information to be passed to
  2147. them from the main program to operate on.
  2148. Because of their flexibility we will only
  2149. briefly run through some of the different types
  2150. of functions here, the majority of them will be
  2151. covered as and when they come up under
  2152. different logical headings in the tutorial and
  2153. some will be left for you to discover in the
  2154. Command Reference section.
  2155.  
  2156.  
  2157. Mathematical Functions
  2158.  
  2159. We have already seen how the use of different
  2160. arithmetic signs, add, divide, multiply and
  2161. divide can make your computer into a kind of
  2162. calculator. To extend the usefulness of these
  2163. MaxonBASIC comes with an extensive range of
  2164. mathematical functions. COS and LOG are two
  2165. examples:
  2166.  
  2167.  
  2168. PRINT COS(45)
  2169. y = LOG(x) : PRINT y
  2170.  
  2171.  
  2172. Text Functions
  2173.  
  2174. Most text functions are designed to perform
  2175. operations on existing text strings. They will
  2176. therefore be covered in depth in the section
  2177. Strings and Things.
  2178. Exceptions include two text functions that are
  2179. designed to create new strings - SPACE$ and
  2180. STRING$.
  2181.  
  2182.  
  2183. A$ = SPACE$(10)
  2184.  
  2185.  
  2186. will create a new string of ten spaces, which
  2187. can be printed or assigned to a variable.
  2188. STRING$ can be used to produce a string of
  2189. specified length made up of a chosen character
  2190. repeated:
  2191.  
  2192.  
  2193. x = 23
  2194. PRINT STRING$(x,"*")
  2195. which will print:
  2196.  
  2197. ***********************
  2198.  
  2199.  
  2200. Miscellaneous Functions
  2201.  
  2202. There are a wide selection of functions
  2203. available that fit into no neat category, but
  2204. just perform a useful job. Two simple examples
  2205. are DATE$ and TIME$ which return the
  2206. appropriate values from the computer for
  2207. display within your own programs.
  2208.  
  2209.  
  2210. PRINT DATE$
  2211.  
  2212.  
  2213. may give the answer
  2214.  
  2215.  
  2216. 22-04-1992
  2217.  
  2218.  
  2219. Remember that a function, by definition, must
  2220. return some sort of value or data to the
  2221. program that called it.
  2222.  
  2223.  
  2224. User Defined Functions
  2225.  
  2226. MaxonBASIC has a very generous smattering of
  2227. functions designed to provide you with a wide
  2228. selection of useful tools for manipulating
  2229. data. However it is impossible to predict or to
  2230. cater for every possible eventuality that will
  2231. come up. There will inevitably be times when
  2232. you will want to use functions that do not come
  2233. supplied. Fortunately you can then employ User
  2234. Defined Functions to construct new routines to
  2235. meet your own requirements.
  2236. MaxonBASIC differs from many other versions of
  2237. the language in that it allows the user to
  2238. write complex multiple-line functions. These
  2239. have many similarities with sub-programs. They
  2240. can have parameters passed to them (and by
  2241. definition must pass a result back to the
  2242. calling program line). Also, they can use local
  2243. and global variables and as such can easily be
  2244. stored in a pre-written library of routines.
  2245. The keywords used to set up and call a user-
  2246. defined function are FUNCTION / END FUNCTION or
  2247. DEF FN / END DEF / FN. As with sub-programs and
  2248. logical loops the command EXIT FUNCTION / EXIT
  2249. DEF can be used to trigger a jump from the
  2250. function, e.g. if it has been passed a value
  2251. that is outside of the range that you wish to
  2252. permit.
  2253. The name that is used to define a function as
  2254. in the commands:
  2255.  
  2256.  
  2257.  DEF FNname  or  FUNCTION Cube
  2258.  
  2259.  
  2260. is also the name used to call the function
  2261. using the command:
  2262.  
  2263.  
  2264.  FNname  or  cube
  2265.  
  2266.  
  2267. and is also used as a variable, within the
  2268. function definition, which is assigned the
  2269. value that is to be returned to the calling
  2270. program line. Note that there are essentially
  2271. two ways of defining a function; using the FN
  2272. terminology or, more simply, using the FUNCTION
  2273. keyword; we encourage you to use the latter,
  2274. more modern method.
  2275. Here is an example of a mathematical function
  2276. that can be used to convert inches into
  2277. centimetres.
  2278.  
  2279.  
  2280. FUNCTION metric(a)
  2281.  metric = a*2.54
  2282. END FUNCTION
  2283.  
  2284. Mainprogram:
  2285.  Inches = 10
  2286.  CMs = metric(Inches)
  2287.  PRINT Inches; "inches
  2288. equals";CMs;"centimetres"
  2289.  
  2290.  
  2291. The following example of a text function can be
  2292. used to strip trailing and leading spaces from
  2293. any string. It employs one or two pre-defined
  2294. text functions as building blocks; to follow
  2295. these you must refer forward to the section on
  2296. strings, or consult the Command Reference
  2297. section.
  2298.  
  2299.  
  2300. FUNCTION strip$(BYVAL A$)
  2301.  
  2302.  IF LEN(A$)=0 THEN EXIT FUNCTION
  2303.  WHILE LEFT$(A$,1)=" "
  2304.      Length=LEN(A$)
  2305.      A$=RIGHT$(A$,Length-1)
  2306.  WEND
  2307.  
  2308.  WHILE RIGHT$(A$,1)=" "
  2309.      Length=LEN(A$)
  2310.      A$=LEFT$(A$,Length-1)
  2311.  WEND
  2312.  
  2313.  strip$=A$
  2314.  
  2315. END FUNCTION
  2316.  
  2317.  
  2318.   
  2319.   The above example is useful as an exercise
  2320.   but  MaxonBASIC lets you strip leading and
  2321.   trailing spaces with LTRIM$(RTRIM$(A$))!
  2322. If you use a function, declared using FUNCTION,
  2323. before it is defined, you must tell MaxonBASIC
  2324. that you are going to do this by using DECLARE
  2325. FUNCTION name followed by its parameter list,
  2326. at the front of your program. Otherwise the
  2327. compiler may think that you are using an array
  2328. name and not a function call e.g.
  2329.  
  2330.  
  2331. DECLARE FUNCTION Cube (BYVAL x)
  2332.  
  2333.  
  2334. PRINT Cube(5.6)
  2335.  
  2336. FUNCTION Cube(BYVAL x)
  2337.  Cube=x*x*x
  2338. END FUNCTION
  2339.  
  2340.  
  2341. In general, it is a good idea to include all
  2342. your sub-program and function definitions at
  2343. the beginning of your program.
  2344.   
  2345.   Note   that  parameters  passed  to  user-
  2346.   defined  functions defined  using  DEF  FN
  2347.   are,  by default, value parameters  -  you
  2348.   can   force   a   variable  parameter   by
  2349.   including  the  word  VARPTR  before   the
  2350.   variable in the function definition.  Also
  2351.   local  variables within a DEF FN  function
  2352.   are automatically assumed SHARED. This  is
  2353.   all  historical and we have included  this
  2354.   behaviour  in MaxonBASIC to be  compatible
  2355.   with Microsoft QuickBASIC et al.
  2356.   
  2357.   Functions   declared  using  the   keyword
  2358.   FUNCTION do not suffer from this confusing
  2359.   behaviour  towards  parameters  and  local
  2360.   variables  -  they behave in  exactly  the
  2361.   same  way as sub-programs; parameters are,
  2362.   by  default, variable and local  variables
  2363.   are,  by  default,  STATIC.  Therefore  we
  2364.   advise you, most strongly, to use FUNCTION
  2365.   and not DEF FN, which is provided only for
  2366.   backward compatibility.
  2367.  
  2368.  
  2369. More about Numbers & Text
  2370.  
  2371. The ways that MaxonBASIC handles data,
  2372. particularly numbers, is very much more complex
  2373. than we have seen so far. This is not sadism on
  2374. the part of the designers but is in fact
  2375. essential (honest!).
  2376. In every day conversation we all use numbers in
  2377. a variety of ways and, most of the time, other
  2378. people manage to work out exactly what we mean.
  2379. For example you may say to someone ´I´ll be
  2380. around in ten minutes´ and it is understood
  2381. that you could in fact be eight, twelve or even
  2382. twenty minutes. Conversely if you say ´I want
  2383. to collect that ten pounds you owe me´ you will
  2384. be rather unhappy to receive any less than
  2385. that. The essential difference between the two
  2386. is the precision of the figures we use and the
  2387. implicit understanding of the person to whom we
  2388. are communicating.
  2389. The problem is that while people are able to
  2390. use their experience to interpret what you
  2391. probably mean, a computer takes everything much
  2392. more literally. It will expect you to turn up
  2393. in exactly 600 seconds to collect your 1000
  2394. pence.
  2395. As if that was not enough, even computers,
  2396. which insist that you say exactly what you
  2397. mean, do not always mean exactly what they
  2398. appear to say. What would you make of a
  2399. calculator that claimed that two plus two did
  2400. not equal four. Not much probably, but it is
  2401. actually possible for this to happen.
  2402. Numbers that look quite simple to the user,
  2403. such as ´4´, may in fact be stored as very much
  2404. longer figures e.g. ´4.00012´. These slight
  2405. aberrations from what the user sees, or means
  2406. when typing in figures, result from minute
  2407. rounding errors in the way that the
  2408. calculations are performed internally.
  2409. Obviously, this state of affairs can not be
  2410. left to operate randomly. Small rounding errors
  2411. of this sort, when added together or multiplied
  2412. can eventually result in visibly different
  2413. answers from that which is expected.
  2414. We therefore have different ways of expressing
  2415. numbers and numeric variables in MaxonBASIC
  2416. that will control the degree of precision that
  2417. you want the calculations to work to, and can
  2418. force numbers to change their internal format
  2419. to ensure that they achieve the desired result.
  2420. The most important distinction is between
  2421. integer and floating point numbers. An integer
  2422. number is a whole number, i.e. there can be no
  2423. decimal fraction. By forcing the computer to
  2424. use integer numbers we can ensure that all
  2425. calculations produce the result that we would
  2426. expect, 2+2 really does equal 4. Integers are
  2427. particularly useful when performing financial
  2428. calculations where it is important that the odd
  2429. penny does not go astray.
  2430. Unfortunately, for unimportant reasons which
  2431. have to do with the way that computers work,
  2432. integer numbers usually have to fit within the
  2433. range +32767 to -32768. In order to maintain
  2434. compatibility with programs that run under
  2435. other versions of BASIC, the MaxonBASIC
  2436. recognises and uses the ordinary integer type
  2437. and the associated commands that allow
  2438. variables to be assigned as integers. However
  2439. this version of the language has also been
  2440. extended to also allow long integers, whole
  2441. numbers in the range 2147483647 to -2147483648.
  2442. Floating point numbers are any numbers that
  2443. have a fractional part, i.e. there is a value
  2444. after the decimal point. Again there are two
  2445. different types of these numbers - single and
  2446. double precision numbers.
  2447. Floating point numbers are often displayed
  2448. using scientific notation consisting of a fixed
  2449. point number (the mantissa) followed by a
  2450. letter E and then an integer which is the
  2451. exponent. To convert this notation to a normal
  2452. format you have to multiply the mantissa by ten
  2453. to the power of the exponent.
  2454. Single precision floating point numbers are
  2455. accurate to seven digits in the mantissa while
  2456. double precision numbers are accurate to 16
  2457. digits in the mantissa. The exact ranges for
  2458. these numbers are given in the Concepts
  2459. chapter.
  2460. For small number values, where there is no
  2461. ambiguity in the precision, numbers will be
  2462. displayed in the normal form. For large numbers
  2463. scientific notation will be used on screen.
  2464. Floating point numbers, and in particular those
  2465. with double precision, use more memory and are
  2466. slower to calculate than long integers, long
  2467. integers are slower and use more memory than
  2468. integers. However the power and speed of
  2469. MaxonBASIC together with the large amount of
  2470. available memory on the Amiga range means that
  2471. these problems are much less noticeable than on
  2472. other micros.
  2473. You will have seen by now that MaxonBASIC does
  2474. not force you to use any of these number format
  2475. commands. As with many other commands, the
  2476. language assumes a default setting of single
  2477. precision if your exact requirements are not
  2478. specified. There are also several associated
  2479. commands that allow numbers of one type to be
  2480. converted to another, for calculation or
  2481. display.
  2482. It is possible to denote explicitly which type
  2483. a number or numeric variable belongs to by the
  2484. use of a certain suffix.
  2485.  
  2486. The % character denotes an integer.
  2487. The & character denotes a long integer.
  2488. The ! character denotes a single precision
  2489. numbers.
  2490. The # character denotes a double precision
  2491. numbers.
  2492. The suffix can be given as part of a number as
  2493. in:
  2494.  
  2495.  x = 234%
  2496. or as part of the variable name in which case
  2497. that particular variable is unable to store
  2498. data of the inappropriate type:
  2499.  
  2500.  x! = 2.34
  2501. Constant literals, i.e. those that are not
  2502. assigned to variables and which therefore will
  2503. not change during the running of the program
  2504. can again be integer, long integer, single or
  2505. double precision floating point.
  2506. Of course any number or variable that looks
  2507. like an integer can be forced to be stored
  2508. internally as a floating point number by use of
  2509. the appropriate suffix. A number or variable
  2510. that has a fractional part can be forced to be
  2511. an integer by assigning it to a variable with
  2512. the % or & suffix and if this is done the
  2513. number will be rounded to the nearest integer.
  2514. In the course of a calculation all numbers are
  2515. converted to the same format as the highest
  2516. precision number used anywhere in the current
  2517. operation. The answer is also returned in a
  2518. form that matches that precision. For example
  2519. in the line:
  2520.  
  2521.  
  2522. x& = 100000& + i%*i%
  2523.  
  2524.  
  2525. i%*i% is evaluated as an integer and will
  2526. overflow if i% is greater than 181. The result
  2527. is added to 100000& and this result is then
  2528. turned into a long integer.
  2529. If an integer number, assigned to an untyped
  2530. variable, undergoes a calculation such that it
  2531. is converted to a number with a decimal
  2532. fraction, i.e. the variable value is
  2533. automatically converted to floating point. If
  2534. the number is assigned to a typed variable the
  2535. result of the calculation will be amended to
  2536. fit that type.
  2537. There are also several associated commands that
  2538. allow numbers of one type to be converted to
  2539. another, for calculation or display, or which
  2540. control the type of number a variable is
  2541. capable of holding.
  2542. The following commands can be used to predefine
  2543. what types of data a given variable name will
  2544. store. They work by specifying the range of
  2545. letters that are to begin the variable names
  2546. for a given data type.
  2547. For example:
  2548.  
  2549.  
  2550. DEFDBL A-C, F
  2551. will mean that all variables that begin with
  2552. the letters A, B, C and F will all be assigned
  2553. double precision values even though in the
  2554. actual statement that gives the value to the
  2555. variable the number could look like single
  2556. precision or even an integer, without any #
  2557. sign.
  2558.  
  2559.  
  2560. DEFSNG range
  2561. will predefine a range of variable names to
  2562. take single precision numbers,
  2563.  
  2564.  
  2565. DEFINT range
  2566. will define them to take integers and
  2567.  
  2568.  
  2569. DEFLNG range
  2570. to take long integers. You can also use
  2571.  
  2572.  
  2573. DEFSTR range
  2574. to define variables to hold strings; this
  2575. allows you to dispense with the $ suffix for
  2576. the relevant string variables although, of
  2577. course, you must still include the $ for MID$,
  2578. LEFT$, LTRIM$ etc.
  2579.  
  2580. All of the above definition commands are useful
  2581. for freeing you from the need to explicitly
  2582. define a variable type as it is being used, but
  2583. they can be over-ridden by the use of the data
  2584. suffixes described above. They are particularly
  2585. valuable for catching input from the user that
  2586. is required to be of a particular numeric type.
  2587. There are a suite of commands that change the
  2588. internal format of a given numeric variable
  2589. into another type.
  2590.  
  2591.  
  2592.  
  2593. CSNG(x)
  2594. converts x to a single precision number,
  2595.  
  2596.  
  2597.  
  2598. CDBL(x)
  2599. converts x to a double precision number,
  2600.  
  2601.  
  2602.  
  2603. CINT(x)
  2604. converts x to an integer and
  2605.  
  2606.  
  2607.  
  2608. CLNG(x)
  2609. converts x to a long integer. In both of the
  2610. latter cases the fractional parts are rounded
  2611. to the nearest integer. Try this:
  2612.  
  2613. x=22/7
  2614. PRINT CSNG(x), CDBL(x), CINT(x), CLNG(x)
  2615.  
  2616. CLNG is useful for promoting the result of a
  2617. short integer calculation. As we said above,
  2618. 100000& + i%*i% will overflow if i% > 181 but
  2619. 100000& + CLNG(i%)*i% will allow a much wider
  2620. range of values for i%.
  2621. The following commands are functions that act
  2622. on a given variable, to return the integer part
  2623. of that variable, although as you can see there
  2624. are subtle differences in the way they work.
  2625. These functions can be used to assign the
  2626. integer part to a new variable, to print it on
  2627. the screen or to allow it to be used in a
  2628. calculation.
  2629.  
  2630.  
  2631.  
  2632. FIX(x)
  2633. returns the truncated integer part of the
  2634. number, x, i.e. if x is 1.2, FIX(x) returns 1.
  2635. Similarly if x is 22.99, FIX(x) will return 22
  2636. - it always rounds down with positive numbers.
  2637. For negative numbers FIX still truncates the
  2638. figures such that the overall effect is one of
  2639. rounding up. If x is -22.99, FIX(x) will return
  2640. -22.
  2641.  
  2642.  
  2643.  
  2644. INT(x)
  2645. returns the largest integer less than or equal
  2646. to x. For positive numbers the effect is the
  2647. same as FIX(x) but for negative numbers INT
  2648. rounds down. If x is -22.99, INT(x) will return
  2649. -23.
  2650. Finally there are two special arithmetic
  2651. operators - MOD and \ (backslash) which are
  2652. used for integer division.
  2653. In an arithmetic expression such as 20.4\5.2
  2654. the backslash command stands for integer
  2655. division such that both numbers are rounded to
  2656. the nearest integers before the division takes
  2657. place. The answer is also an integer value.
  2658. The keyword MOD returns the remainder of an
  2659. integer division as an integer. 33.2 MOD 5
  2660. would return the value 3.
  2661.  
  2662.  
  2663. Yet More Numbers - Bases
  2664.  
  2665. There is one more aspect of the way that
  2666. numbers are stored and used that needs to be
  2667. covered. In conversation we use exclusively
  2668. decimal numbers, each column in a large number
  2669. represents ten times the number to the right.
  2670. This is known as base ten arithmetic. However
  2671. there is no reason why we have to be restricted
  2672. just to that system.
  2673. In their deepest darkest parts computers work
  2674. exclusively in binary or base two arithmetic.
  2675. Binary digits are either on or off and these
  2676. two available options are used to build up
  2677. larger and larger numbers. Each column in a
  2678. large number represents twice the column to the
  2679. right of it. In binary arithmetic 0 stands for
  2680. 0, 1 for 1, 10 for 2, 11 for 3, 100 for 4, 101
  2681. for 5, 110 for 6, 111 for 7, 1000 for 8 etc.
  2682. However binary arithmetic soon gets unwieldy
  2683. for people to use as the numbers increase in
  2684. length rapidly, and are almost impossible to
  2685. identify by just casual inspection. Programmers
  2686. therefore tend to use the larger base eight
  2687. (octal) arithmetic or base sixteen
  2688. (hexadecimal) arithmetic. Because eight and
  2689. sixteen are both powers of the number two, both
  2690. octal and hexadecimal numbers have much more in
  2691. common with the way that computers actually
  2692. work than ordinary decimal numbers, and allow
  2693. us to see patterns in the data that are
  2694. meaningful to the computer.
  2695. Because these number bases are usually used for
  2696. direct manipulation of the computer memory or
  2697. similar, and would hardly ever be used for
  2698. other calculations, we do not make provision to
  2699. use fractional parts of numbers expressed in
  2700. octal or hexadecimal - they are all expressed
  2701. as the equivalents of decimal integers.
  2702. The command
  2703.  
  2704.  
  2705. OCT$(x)
  2706. will convert the (rounded) integer part of the
  2707. number x to its octal equivalent. The result is
  2708. stored as a string variable to avoid ambiguity,
  2709. i.e. to ensure that calculations can not be
  2710. attempted directly with octal numbers.
  2711.  
  2712.  
  2713. HEX$(x)
  2714. provides a similar conversion to hexadecimal.
  2715. We have a problem with hexadecimal numbers that
  2716. does not crop up in any base less than ten. We
  2717. need a system for expressing numbers in the
  2718. range 10-15 with just one figure. The
  2719. convention used to do this is to use the letter
  2720. A to stand for 10, B for 11, C for 12, D for
  2721. 13, E for 14 and F for 15. So 8 = 8, B = 11, 10
  2722. = 16, 15 = 21, 1A = 26 and FF = 255.
  2723. Note for example that the total number of ASCII
  2724. codes range from 0-255 and 255 is the binary
  2725. number 11111111, and the hexadecimal number FF
  2726. (both of which look much more significant than
  2727. 255). This demonstrates how using other bases
  2728. can be helpful in denoting meaningful numbers.
  2729. MaxonBASIC allows the use of prefixes &B, &H
  2730. and &O (O as in ÒOhÓ rather than ÒZeroÓ!) for
  2731. specifying binary, hexadecimal and octal
  2732. constants respectively - see the Concepts
  2733. chapter for a full discussion of these
  2734. different base constants.
  2735. Having broached the issue of how computers
  2736. store and use numbers internally, it is
  2737. probably worth pushing on with the subject as
  2738. some terms will inevitably come up in later
  2739. parts of the tutorial. The following brief
  2740. explanation is not essential reading at this
  2741. stage but will become increasingly important as
  2742. your programs become more sophisticated.
  2743.  
  2744.  
  2745. How Computer Numbers Work
  2746.  
  2747. Computers store all numbers and data internally
  2748. in units known as bytes. A byte is an eight
  2749. digit binary number that ranges from 00000000
  2750. to 11111111 which is 0 to 255 decimal or 0 to
  2751. FF in hexadecimal.
  2752. Each digit in the binary representation of the
  2753. number is known as a bit, this is short for
  2754. Binary digIT. There are therefore eight bits to
  2755. the byte.
  2756. However as microcomputers have become more
  2757. sophisticated and powerful this relatively
  2758. small size of data has become something of a
  2759. bottleneck to performance. Routines that needed
  2760. to work on large numbers for example had to
  2761. retrieve the data in small ´byte sized´ pieces,
  2762. reconstruct the number in question, act on that
  2763. data, break down the result into small pieces
  2764. again and send it back into the memory. Most
  2765. computer languages perform all of these tasks
  2766. invisibly and the user knows little or nothing
  2767. about it but there was an inevitable penalty in
  2768. speed.
  2769. For more rapid movement and manipulation of
  2770. data there has developed a need for larger data
  2771. ´packets´. As well as the byte we now have the
  2772. larger two byte equivalent, the sixteen bit
  2773. word and the four byte equivalent, the thirty-
  2774. two bit long word.
  2775. Within MaxonBASIC, integers are held in 16 bits
  2776. and long integers in 32 bits. These give the
  2777. numbers -32768 up to 32767 for integers and -
  2778. 2147483648 up to 2147483647 for long integers.
  2779. The reason that integers do not give 0 to 65535
  2780. is that it is generally more useful to use
  2781. signed numbers rather than unsigned although
  2782. some languages do give you the ability to
  2783. choose between signed and unsigned integers.
  2784. Using signed integer arithmetic means that, in
  2785. any integer, if the most significant (the
  2786. leftmost bit) is set to 1 then the number is
  2787. negative.
  2788. Remember, it is perfectly possible to program
  2789. in MaxonBASIC without concerning yourself with
  2790. any of these details. It is only when starting
  2791. to manipulate the memory of the computer
  2792. directly that they will become important.
  2793.  
  2794.  
  2795. Using Logical Operators in Arithmetic
  2796.  
  2797. We have already seen how logical operators
  2798. function to enable tests to be made between two
  2799. different situations. The way these actually
  2800. work internally is based on comparisons between
  2801. the electronic patterns of two binary numbers -
  2802. bitwise comparisons. In the case of a logical
  2803. test the numbers that are usually compared are
  2804. -1 (or another non-zero number) and O standing
  2805. for true and false. Depending on the particular
  2806. type of logical test that is made, the results
  2807. of the comparisons will themselves resolve to a
  2808. figure that will signify either true or false
  2809. and the flow of the program will be altered in
  2810. response.
  2811. You can also use these logical tests in
  2812. expressions; the two operands will be converted
  2813. to integers (or long integers) and then into
  2814. binary and compared, bit by bit, according to
  2815. which logical operator you are using, to obtain
  2816. the result.
  2817. The following table shows the outcome of the
  2818. comparison of each bit for the different
  2819. logical operators:
  2820.  
  2821.  
  2822.  
  2823.            1 and   0 and   1 and  0 and 1
  2824.              1       0       0
  2825.     NOT      0       1       0       1
  2826.     AND      1       0       0       0
  2827.     OR       1       0       1       1
  2828.     XOR      0       0       1       1
  2829.     IMP      1       1       0       1
  2830.     EQV      1       1       0       0
  2831. The type of comparisons that are made need not
  2832. be confined to just true and false however,
  2833. they can be used in just the same way to
  2834. compare and modify two different binary numbers
  2835. such as 10010011 and 11011110. They can
  2836. therefore be used in the following way, for
  2837. example:
  2838.  
  2839.  
  2840. PRINT 162 AND 48
  2841.  
  2842.  
  2843. will be calculated by bitwise-ANDing the two
  2844. binary representations of these integers as is:
  2845. 162 AND 48  is
  2846.  
  2847.  
  2848.  
  2849.  
  2850. 00000000 10100010  AND
  2851. 00000000 00110000
  2852. _________________
  2853. 00000000 00100000  = 32
  2854.  
  2855.  
  2856. Note that we show, and calculate with, the full
  2857. width (16 bits) of the binary representation of
  2858. the integer - this is particularly important
  2859. when using the operators NOT, EQV and IMP which
  2860. may change a 0 bit to a 1 bit and thus often
  2861. turn a positive number into a negative number.
  2862. See if you can predict the outcome of this
  2863. program before you run it :
  2864.  
  2865.  
  2866. SUB L_Table(VAL x,y)
  2867. REM Set tab width to 9
  2868. WIDTH 80,9
  2869. PRINT "X","Y", "X AND Y", "X OR Y", "X XOR Y",
  2870. PRINT "X EQV Y", "X IMP Y", "NOT X"
  2871. PRINT
  2872. PRINT x, y, x AND y , x OR y, x XOR y,
  2873. PRINT x EQV y, x IMP y, NOT x
  2874. PRINT
  2875. END SUB
  2876.  
  2877. j=33
  2878. FOR i=4 TO 7
  2879. CALL L_Table (i,j)
  2880. NEXT i
  2881.  
  2882.  
  2883. These logical transformations are not of
  2884. obvious use to the novice programmer but are
  2885. extremely important for use in graphics work.
  2886. XOR in particular has a useful effect that
  2887. fairly easy to demonstrate.
  2888. Consider this:
  2889.  
  2890. 162 XOR 48 gives:
  2891.  
  2892. 00000000 10100010  XOR
  2893. 00000000 00110000
  2894. 00000000 10010010  =  146
  2895. Now what about 146 XOR 48?
  2896.  
  2897. 00000000 10010010  XOR
  2898. 00000000 00110000
  2899. 00000000 10100010  =  162
  2900.  
  2901.  
  2902. So, XORing a number with a constant and then
  2903. XORing the result with the same constant gives
  2904. us the original number. Because of this
  2905. feature, XOR is used a in computer graphics to
  2906. produce ´non-destructive´ animation i.e. to
  2907. allow pictures to move around on a screen
  2908. without permanently obliterating what was in
  2909. the background. First a certain graphics
  2910. pattern is XORed onto the screen memory and
  2911. hence displayed. XORing the same pattern a
  2912. second time restores exactly the image that was
  2913. there previously. The pattern is then
  2914. repositioned slightly and XORed again to give
  2915. the impression of movement across the screen.
  2916. The ability to XOR graphics images is
  2917. implemented in the PUT statement, as shown in
  2918. the following example.
  2919.  
  2920.  
  2921. REM Simple use of GET and PUT
  2922.  
  2923. DIM Amiga%(1000)
  2924.  
  2925. ´ Draw a box starting at (100, 50)
  2926. LINE (100, 50) - (150, 150), 1, BF
  2927.  
  2928. ´ Get entire box
  2929. GET (100, 50) - (150, 150), Amiga%
  2930. CLS
  2931. FOR i = 0 TO 100 STEP 5
  2932.  PUT (i, i), Amiga%, XOR
  2933.  SLEEP
  2934.  PUT (i, i), Amiga%, XOR
  2935.  SLEEP
  2936. NEXT i
  2937.  
  2938.  
  2939. Type in this program and run it. Now repeatedly
  2940. hit any key, as quickly as you like, to watch a
  2941. black box appear and disappear while moving
  2942. across the screen.
  2943. You might like to save this program. Make sure
  2944. you have a disk in drive DF0 with enough space
  2945. on it (or room on your hard disk) and then
  2946. select Save asÉ from the Project menu.
  2947. A file selector will appear (this is the WB3
  2948. ASL file selector, yours may be slightly
  2949. different).
  2950.                        
  2951.                        
  2952. Type in the name you want to call your program
  2953. (say Amiga.bas). Now click on Save or hit
  2954. Return.
  2955.  
  2956.  
  2957. Strings and Things
  2958.  
  2959. Strings, or text variables, differ from numbers
  2960. in that, at least as far as the computer is
  2961. concerned, there is no logical relationship
  2962. between one character and the next - they are
  2963. just a collection of letters and numbers
  2964. ´strung´ together.
  2965. Unlike decimal numbers where each character
  2966. position signifies a tenfold relationship with
  2967. the one to the right, strings cannot be used in
  2968. calculations. This is true even when they look
  2969. like numbers.
  2970. At times this distinction is very valuable - in
  2971. calculating programs such as spreadsheets for
  2972. example you can ask for a total of all numbers
  2973. in a large block of data without worrying that
  2974. the computer will also include bank account or
  2975. telephone numbers as well.
  2976. However there are certain manipulations we can
  2977. do with strings that are impossible with
  2978. numbers. Long strings can be built up from
  2979. shorter ones by a process called concatenation,
  2980. which really just means adding them together -
  2981. try this:
  2982.  
  2983.  
  2984. A$="Hello"
  2985. B$="John"
  2986. C$=A$+" "+B$
  2987. PRINT C$
  2988.  
  2989.  
  2990. This can be very useful for creating complex
  2991. display layouts for example by making strings
  2992. of tab characters - CHR$(9) - and by using
  2993. carriage return codes - CHR$(13).
  2994. Dividing strings into smaller portions is known
  2995. as string slicing. The following functions all
  2996. return strings that are at most equal to, or in
  2997. some way smaller than, the original that they
  2998. were given as an argument.
  2999.  
  3000.  
  3001. LEFT$(string$,x)
  3002. will return the first x characters counting
  3003. from the left of the string.
  3004.  
  3005.  
  3006. RIGHT$(string$,x)
  3007. will return the first x characters from the
  3008. right of the string.
  3009.  
  3010.  
  3011. MID$(string$,a,x)
  3012. returns a string of x characters long starting
  3013. from the position a in the original (the
  3014. required length, x, can be omitted in which
  3015. case the entire remainder of the string is
  3016. returned).
  3017. MID$ can also be used to alter the data held
  3018. within a string by specifying a portion that is
  3019. to be replaced with a second string using the
  3020. syntax:
  3021.  
  3022.  
  3023. MID$(string$,a,x)=string2$
  3024.  
  3025.  
  3026. This will replace x characters from string,
  3027. starting at position a, with the first x
  3028. characters from string2.
  3029.  
  3030.  
  3031. INSTR(a,string$,string2$)
  3032. will search for the first occurrence of string2
  3033. within string starting optionally from position
  3034. a. If the second string is found the function
  3035. returns the position of the first character of
  3036. that string. Try this:
  3037.  
  3038.  
  3039. SUB Search (BYVAL A$)
  3040. IF INSTR(1,A$,"HiSoft")<>0 THEN
  3041.  
  3042.  PRINT "That´s what we like to see!"
  3043. ELSE
  3044.  PRINT "Where´s the HiSoft?"
  3045. END IF
  3046. END SUB
  3047.  
  3048. DO
  3049.  INPUT "Gimme some words, please";Test$
  3050.  Search Test$
  3051. LOOP UNTIL Test$=="END"
  3052.  
  3053.  
  3054. The opposite of INSTR is RINSTR; this searches
  3055. backwards through a string starting at the end.
  3056. See if you can work out what this does:
  3057.  
  3058.  
  3059. INPUT a$
  3060. DO
  3061.  i-RINSTR(a$," ")
  3062.  IF i=0 THEN EXIT LOOP
  3063.  PRINT MID$(a$,i+1); " ";
  3064.  a$=LEFT$(a$,i-1)
  3065. LOOP
  3066.  
  3067.  
  3068. These commands can be used in conjunction with
  3069. each other to build up more complex string
  3070. manipulation expressions. They work well in
  3071. conjunction with the function:
  3072.  
  3073.  
  3074. LEN(string$)
  3075. that returns the length of the string in
  3076. question.
  3077.  
  3078. LSET and RSET can be used to place a string of
  3079. text within a string variable of greater length
  3080. such that the smaller string is assigned flush
  3081. with either the left hand end (left-justified)
  3082. or the right hand end (right-justified) of the
  3083. larger. For these commands to work you must
  3084. first create a larger string of the required
  3085. size and the easiest way to do this is to use
  3086. either the SPACE$ or the STRING$ commands. LSET
  3087. and RSET are normally used when using files and
  3088. FIELDed variables but can be used to left- and
  3089. right-justify any string.
  3090.  
  3091.  
  3092. A$=STRING$(30," ")
  3093. B$="HELLO!"
  3094. PRINT A$
  3095. PRINT B$
  3096. RSET A$=B$
  3097. PRINT A$
  3098. LSET A$=B$
  3099. PRINT A$
  3100.  
  3101.  
  3102. To illustrate the use of some of the above
  3103. functions here is one that can be used as a
  3104. complement to RSET and LSET to centre one text
  3105. string within another.
  3106.  
  3107.  
  3108. FUNCTION centre$(main$,insert$)
  3109. STATIC a,b
  3110.  
  3111.  a = LEN(main$)
  3112.  b = LEN(insert$)
  3113.  IF b >= a THEN
  3114.  
  3115.      FNcentre$ = LEFTS(insert$ ,a) : EXIT
  3116. FUNCTION
  3117.  END IF
  3118.  c = (a-b)\2       ´ integer division
  3119.  MID$(main$, c+1) = insert$
  3120.  centre$ = main$
  3121. END FUNCTION
  3122.  
  3123. DO
  3124.  INPUT "A word";a$
  3125.  INPUT "Another word";b$
  3126.  PRINT centre$(a$,b$)
  3127. LOOP UNTIL a$=="END"
  3128.  
  3129.  
  3130. UCASE$ and LCASE$ convert all letters within a
  3131. given string into upper case or lower case
  3132. respectively. These are useful routines for
  3133. tidying up the response given by a user:
  3134.  
  3135.  
  3136. DO
  3137.  INPUT "What is your name"; A$
  3138. LOOP UNTIL A$<>""
  3139. B$ = UCASE$(A$)
  3140. PRINT "HELLO "; B$
  3141.  
  3142.  
  3143. Of course punctuation and numbers within the
  3144. string remain unchanged.
  3145.  
  3146.  
  3147. Numbers to Text and Back Again
  3148.  
  3149. We have already touched on the subject of how
  3150. letters are actually stored internally in the
  3151. computer as numbers. These are known as ASCII
  3152. (American Standard Code for Information
  3153. Interchange) numbers and every letter or
  3154. character that you can type with your Amiga
  3155. will have its own internal ASCII number.
  3156. Obviously it is vitally important that the
  3157. computer knows at any one time whether the
  3158. numbers it has stored in its memory are
  3159. actually to be regarded as numbers or whether
  3160. they really represent text.
  3161. Say for example that you have stored on a file
  3162. somewhere your telephone number 0525718181. It
  3163. will be essential that your programs are aware
  3164. that this is actually a text representation of
  3165. a number rather than a true number. It cannot
  3166. be multiplied by any other figure, divided,
  3167. assigned to a numeric variable, converted to
  3168. double precision and so on, and in particular
  3169. it should never be used to calculate your
  3170. taxable income by your home accounts program!
  3171. It is to avoid such ambiguity that computer
  3172. languages such as MaxonBASIC insist that text
  3173. variables are denoted by the suffix $ and the
  3174. text strings themselves are enclosed in quotes.
  3175. However there are situations where it is
  3176. important that the programmer has control over
  3177. the way that the internal numbers are handled.
  3178. It is possible to convert numeric variables to
  3179. text, and vice versa, and we shall see that
  3180. there are certain advantages to doing so.
  3181.  
  3182. Text as numbers - the ASCII codes
  3183. Although text is always stored in memory as
  3184. ASCII numbers the computer keeps track of which
  3185. variables really represent letters and need to
  3186. be converted to such before displaying them on
  3187. the screen. There are however circumstances
  3188. where it is valuable for the programmer to be
  3189. able to access these numbers directly and
  3190. decide what to do with them.
  3191. A typical situation may be where text data is
  3192. stored in an unstructured way in memory, which
  3193. could happen if it has been imported from
  3194. another computer through one of the expansion
  3195. ports. The actual data read and stored will be
  3196. the ASCII number equivalents of that text.
  3197. At a later stage if you wish to display the
  3198. information on screen you will have to
  3199. explicitly signal to the computer that you want
  3200. the data to be interpreted as letters rather
  3201. than as numbers - unlike defined variables the
  3202. computer will be unable to guess what each
  3203. piece of data is to represent.
  3204. The keyword we use to convert a stored ASCII
  3205. number to its text equivalent is CHR$(). Within
  3206. the brackets we should put either a number or a
  3207. numeric variable name. The computer will then
  3208. convert this number to text using its internal
  3209. ASCII table.
  3210. The following short example will illustrate the
  3211. way that the conversion of ASCII numbers to
  3212. text works:
  3213.  
  3214.  
  3215. a = 72
  3216. b = 69
  3217. c = 76
  3218. PRINT CHR$(a);CHR$(b);CHR$(c);CHR$(c);CHR$(79)
  3219.  
  3220.  
  3221. which will produce the message HELLO.
  3222. It may seem a cumbersome way of doing things,
  3223. but storing text in this way can be extremely
  3224. useful. In particular it is valuable when you
  3225. want to print or display characters that cannot
  3226. actually be typed at the keyboard.
  3227. As well as producing some of the more unusual
  3228. characters, different ASCII numbers can be used
  3229. by your programs to trigger special effects.
  3230. Data files created by word processors, text
  3231. editors and the like will contain ASCII
  3232. numbers. Similarly all information exchange
  3233. from the keyboard to the computer, from the
  3234. computer to the printer, from the computer to
  3235. the disk drive and from the computer to another
  3236. computer will be as ASCII information. However
  3237. what happens to that information when it
  3238. arrives depends on the program that is running
  3239. and on the computer´s operating system.
  3240. For example, when ASCII codes are sent to the
  3241. printer they do not all appear on paper. Some
  3242. are regarded as control codes that instead
  3243. trigger some sort of special effect. One such
  3244. special effect code is ASCII number seven which
  3245. produces a beep, either from the computer or
  3246. the printer depending on where the code has
  3247. been sent.
  3248. Another very important control code number is
  3249. ASCII 27 which is known as the escape code.
  3250. Most printers use this to signal the start of
  3251. some command sequence that will produce a
  3252. different type style such as bold or enlarged
  3253. print or some other effect.
  3254. Many software programs will use their own
  3255. routines to catch certain ASCII codes coming
  3256. from the keyboard and to use them to trigger
  3257. actions. One might do a simple test on which
  3258. letter has been sent, but again ASCII codes are
  3259. usually more flexible as it is possible to
  3260. select unusual numbers that can only be ´typed´
  3261. by some combination of letters such as Ctrl-X
  3262. which in the Amiga keyboard produces the
  3263. character number 24. Alternatively an unusual
  3264. code or sequence of codes can be assigned to
  3265. one of the ten function keys.
  3266. One of the most common and important ASCII
  3267. control codes you will ever use is number 10
  3268. which is the code for line feed. This is the
  3269. code which is sent whenever you press the
  3270. Return key on your keyboard and signal the end
  3271. of one line and the start of the next when you
  3272. are typing e.g. using your MaxonBASIC editor.
  3273. These codes are also extremely useful for
  3274. controlling the display of information on the
  3275. screen. Say you want to define the text
  3276. variable ADDRESS$ to produce this output:
  3277.  
  3278.  
  3279. John Smith
  3280. 22 Long Lane
  3281. Newtown
  3282.  
  3283.  
  3284. You can achieve this by using, all on one line:
  3285.  
  3286.  
  3287. ADDRESS$="John Smith"+CHR$(10)+"22 Long
  3288. Lane"+CHR$(10)+"Newtown"
  3289.  
  3290.  
  3291. There is an associated keyword which will
  3292. return the ASCII number for any given letter or
  3293. text variable. This command is ASC(). Example:
  3294.  
  3295.  
  3296. PRINT ASC("A") : PRINT ASC("*")
  3297.  
  3298.  
  3299. Sometimes the keyword ASC() is not appropriate
  3300. because it always converts the characters to
  3301. their ASCII table equivalent rather than to
  3302. what we would regard as their direct numeric
  3303. equivalent.
  3304. For example the text character 9 has the ASCII
  3305. value of 57. The following line would therefore
  3306. give the answer of 570.
  3307.  
  3308.  
  3309. x = ASC("9") : PRINT x * 10
  3310.  
  3311.  
  3312. What we need in this case is VAL. VAL searches
  3313. a string expression for anything that can be
  3314. interpreted as a number, integer or floating-
  3315. point.
  3316. Try these out:
  3317.  
  3318.  
  3319. x = VAL("9") : PRINT x * 10
  3320. PRINT VAL("180 High Street North")
  3321. PRINT VAL("   -256+40=-216")
  3322. a$="26.04 - the price plus VAT")
  3323. PRINT VAL(a$)
  3324.  
  3325.  
  3326. VAL stops looking for a number as soon as it
  3327. encounters something (apart from a space, tab
  3328. or end-of-line) that it thinks cannot start a
  3329. number.
  3330.  
  3331. Numbers as text
  3332. Converting numbers to characters is essential
  3333. whenever they are to be incorporated into a
  3334. long string of text, or imported into a text
  3335. data file such as one produced by a word
  3336. processor etc. There are however other possible
  3337. advantages in making the conversion.
  3338. We have already seen how text strings can be
  3339. sliced into smaller pieces, or joined together,
  3340. and in several ways manipulated in a very
  3341. different manner to numeric variables. There
  3342. are often occasions where it is useful to be
  3343. able to do the very same things to numbers.
  3344. We have already seen above how to take a string
  3345. and extract a number from it using VAL; the
  3346. converse of this is where you want to convert a
  3347. number into a text string - for this you use
  3348. STR$. STR$ inserts a leading space or a minus
  3349. sign, if the number is non-zero.
  3350.  
  3351.  
  3352. a=1066 : b$=STR$(a)+" and all that!"
  3353. PRINT b$
  3354. big=-98765.43 : b$=STR$(big)
  3355. PRINT LEFT$(b$,3);",";RIGHT$(b$,LEN(b$)-3)
  3356.  
  3357.  
  3358. More Ways to Store Variables and Data
  3359.  
  3360. Computers are used all around us today, in
  3361. almost every profession, business or service
  3362. you can name, to store and manipulate large
  3363. amounts of data. In many ways the use of
  3364. variables lies at the heart of this power. For
  3365. example a simple arithmetic expression can be
  3366. placed inside of a logical loop and within a
  3367. couple of hours it could have done literally
  3368. thousands upon thousands of calculations if it
  3369. was given a constant supply of numbers to work
  3370. from. But where can this data come from?
  3371. We obviously need a way to store and read data
  3372. that is less longwinded than the simple, hard-
  3373. coded system we have employed so far of
  3374. variablename = data or every business program
  3375. would need thousands of lines that did nothing
  3376. but assign values to variables (if you could
  3377. think of enough names for them).
  3378. We have already mentioned disk files and these
  3379. will often be the most common way of storing
  3380. large amounts of variable data on your Amiga.
  3381. However, for storing reasonably small amounts
  3382. of data that is to be constant over the life of
  3383. your program the DATA, READ and RESTORE
  3384. commands are useful.
  3385. The keyword DATA is used to supply a list of
  3386. several items of data, each separated from the
  3387. next by commas. There can be many such DATA
  3388. lines within each program. The keyword READ is
  3389. used to look up this data, item by item, and
  3390. assign it to a named variable, or several
  3391. variables in turn (with the usual proviso that
  3392. string data should not be assigned to a numeric
  3393. variable etc.). When reading from the list
  3394. MaxonBASIC starts at the very first DATA line
  3395. it finds. When finished it remembers its exact
  3396. position in the list, ready to begin again
  3397. following the next READ command.
  3398. The ´pointer´ that the computer uses to keep
  3399. track of its position within the list can be
  3400. moved with the use of the RESTORE command. If
  3401. used on its own RESTORE resets this pointer to
  3402. the front of the first DATA line, but RESTORE
  3403. can also be used with a specified line number
  3404. or line label to move the pointer more
  3405. selectively.
  3406. Text string data within the list does not have
  3407. to be enclosed within quotes but you will get
  3408. an error if you try to read such data into a
  3409. numeric variable.
  3410. Try this little program:
  3411.  
  3412.  
  3413. DATA "A Box" ´ quotes because of space
  3414. character
  3415. DATA 100,50,100,150,200,150,200,50
  3416. RESTORE
  3417. READ a$
  3418. LOCATE 4,18
  3419. PRINT a$
  3420. x0=200 : y0=50
  3421. FOR a=1 to 4
  3422.  READ x1,y1
  3423.  LINE (x0, y0) - (x1, y1)
  3424.  x0=x1 : y0=y1
  3425. NEXT a
  3426.  
  3427.  
  3428. Another system for storing large amounts of
  3429. information is the use of dimensioned
  3430. variables. These allow information to be held
  3431. in a much more dynamic way than is possible
  3432. with DATA statements, but make the organisation
  3433. and management of the data much easier than
  3434. with simple variables.
  3435. The keyword used to produce a dimensioned
  3436. variable is DIM.
  3437. A dimensioned variable allows several items of
  3438. information to be accessed under just one
  3439. variable name by specifying a numeric position
  3440. for the data within a list. Take this example:
  3441.  
  3442.  
  3443. DIM x(12)
  3444.  
  3445.  
  3446. This dimensions the variable x to hold 13
  3447. entries of data each accessed in turn as x(0),
  3448. x(1), x(2), x(3), x(4), x(5), x(6), x(7), x(8),
  3449. x(9), x(10), x(11) and x(12). This list of
  3450. variables, all stored under the same name, is
  3451. known as an .ib.array;. Data is placed in each
  3452. of the entries of a dimensioned variable in
  3453. just the same way as with a normal variable
  3454. e.g.
  3455.  
  3456.  
  3457. DIM A$(21)
  3458. a$(12) = "Fred Smith"
  3459.  
  3460.  
  3461. It is also possible to define a two dimensional
  3462. array as in DIM x(9,9) which will store
  3463. 10*10=100 items of integer data. The data in a
  3464. two dimensional array can be accessed as if
  3465. part of a table, with each data item read by
  3466. specifying the ´row´ and ´column´ number.
  3467. Similarly a three dimensioned array can be made
  3468. which can be looked on as perhaps many
  3469. different tables held on several pages of a
  3470. book. Three dimensions is the limit to what we
  3471. can visualise in terms of everyday objects but
  3472. the number of dimensions you can have in an
  3473. array is unlimited.
  3474. Arrays of this form can be used to store data
  3475. in a highly structured way. For example a
  3476. series of string variables used by an address
  3477. book program can be subdivided to store names,
  3478. addresses, home telephone numbers, work
  3479. address, work telephone number etc. and chosen
  3480. parts of the data can be called up by
  3481. specifying the appropriate array position.
  3482. It is not always necessary to use the DIM
  3483. command when using dimensioned variables. Any
  3484. variable name that is given an array position
  3485. when it is first used will automatically
  3486. trigger the formation of a dimensioned array of
  3487. that name as in:
  3488.  
  3489.  
  3490. X(2)=20
  3491. PRINT X(1)
  3492.  
  3493.  
  3494. However when this system is used it creates a
  3495. default array size of just 11 elements in each
  3496. dimension referred to in the variable name.
  3497.   
  3498.   MaxonBASIC  provides  a  range  of   error
  3499.   checks on arrays which are controlled  via
  3500.   the   compiler  options  requesters.  With
  3501.   Array  checks  on  you  will  be  told  at
  3502.   runtime  if  you access an  array  element
  3503.   beyond  the dimensions of the array.  When
  3504.   you  are  sure that your program  is  safe
  3505.   from  such  errors you may  want  to  turn
  3506.   Array checks off to increase the speed  of
  3507.   the   program  and  decrease   its   size.
  3508.   However, be warned; if you are relying  on
  3509.   the   auto-dimensioning  of  small  arrays
  3510.   described above, it is a good idea to turn
  3511.   Array check warnings on before you declare
  3512.   your  code  finished and turn checks  off.
  3513.   This   will   tell   you   if   you   have
  3514.   accidentally   used   an   array   without
  3515.   dimensioning  it  first.  If  you  run   a
  3516.   program which uses an un-DIMed array  with
  3517.   Array  checks  off,  a program  crash  may
  3518.   result.
  3519. The SHARED keyword can be used in conjunction
  3520. with DIM to allow the array data to be shared
  3521. between the main program and sub-programs
  3522. without the need for a SHARED statement in each
  3523. sub-program. Thus
  3524.  
  3525.  
  3526. DIM SHARED A$(20)
  3527.  
  3528.  
  3529. in the main program will allow the 21-element
  3530. array A$ to be accessed by all sub-programs.
  3531. Many people find the dimensioning system
  3532. confusing in that an array of say x(10)
  3533. actually stores eleven items of data. This is
  3534. because it includes x(0) as a legal data
  3535. position. The command OPTION BASE 1 forces the
  3536. lowest entry in an array to be position 1, in
  3537. which case DIM x(10) would only allow ten items
  3538. to be stored. You can reset the default
  3539. situation with the command OPTION BASE 0 but
  3540. there are no other options allowed.
  3541. REDIM is a command that allows the size of the
  3542. dimensions of an array to be re-allocated. For
  3543. example DIM x(9,19) can be REDIMensioned to the
  3544. new layout of x(9,39) by:
  3545.  
  3546.  
  3547. REDIM x(9,39)    ´ all data in x() is lost
  3548.  
  3549.  
  3550. Use this command with care as the data that is
  3551. held in the array will be lost.
  3552. REDIM PRESERVE allows one dimensional arrays to
  3553. be enlarged or truncated whilst retaining the
  3554. data in the un-altered array elements.
  3555. When an array no longer is to be used it can be
  3556. ERASEd, which clears all entries and reclaims
  3557. the memory allocated.
  3558. When writing sub-programs the situation often
  3559. arises where the programmer can anticipate that
  3560. the sub-program will be passed a variable array
  3561. as a parameter, but cannot anticipate the
  3562. likely size of this array. Similarly you may
  3563. wish to write program routines that can work on
  3564. an array that may constantly be REDIMensioned.
  3565. MaxonBASIC has two functions which allow the
  3566. size of a given array to be tested.
  3567.  
  3568.  
  3569. UBOUND(name,x)
  3570. returns the highest allowable entry of the
  3571. ´xth´ dimension of the array allocated to the
  3572. variable name.
  3573.  
  3574.  
  3575. LBOUND(name,x)
  3576. will do the same for the lowest allowable entry
  3577. number, which will be either 0 or 1 depending
  3578. on the setting of the OPTION BASE command
  3579. before the array was first dimensioned.
  3580. Finally there is a command that can be used
  3581. with any pair of variables but is particularly
  3582. useful for manipulating and moving around the
  3583. data held in variable arrays.
  3584.  
  3585.  
  3586. SWAP var1,var2
  3587. will exchange the values held in the two
  3588. variables, providing they are both numeric
  3589. variables of the same type, or both string
  3590. variables.
  3591. Below is a complete example using these new
  3592. array handling keywords:
  3593.  
  3594.  
  3595. DEFINT a-z
  3596.  
  3597. SUB Shell_Sort(Words$(1))
  3598. STATIC HowFAR, Top, i, j
  3599.  Top=UBOUND(Words$)
  3600.  HowFar=Top\2
  3601.  DO WHILE HowFar>0
  3602.      FOR i=HowFar TO Top-1
  3603.          j=i-HowFar+1
  3604.          FOR j=(i-HowFar+1) TO 1 STEP -HowFar
  3605.            IF Words$(j)<=Words$(j+HowFar) THEN
  3606.  
  3607.              EXIT FOR
  3608.            END IF
  3609.            SWAP Words$(j), Words$(j+HowFar)
  3610.          NEXT j
  3611.      NEXT i
  3612.      HowFar=HowFar\2
  3613.  LOOP
  3614. END SUB
  3615.  
  3616.  
  3617. Type this shell sort program into MaxonBASIC
  3618. and then devise a means of filling an array
  3619. with some words and calling Shell_Sort to sort
  3620. them into alphabetical order.
  3621.  
  3622.  
  3623. Closing Down
  3624.  
  3625. STOP, END and SYSTEM are all commands that
  3626. produce the effect of stopping the current
  3627. program, closing all files and returning
  3628. control to the calling operating system. They
  3629. can be used as options within an IFÉTHEN branch
  3630. or similar for bringing an end to the program.
  3631. If the current program that is being executed
  3632. ever ´runs out of lines´ the effect is similar
  3633. to placing an END command at the final line.
  3634. SYSTEM differs from END and STOP in that it
  3635. suppresses the Press any key message that
  3636. normally appears when a MaxonBASIC program
  3637. finishes.
  3638.  
  3639.  
  3640. The Screen
  3641.  
  3642. Producing output on the screen is at once one
  3643. of the simplest and one of the most complex
  3644. tasks possible. When you type PRINT "Hello"
  3645. this single command triggers an enormously
  3646. complex series of routines that produce exactly
  3647. the correct pattern of dots on the screen, in
  3648. exactly the correct place amongst the thousands
  3649. of dots that there are, to create the image of
  3650. the word Hello.
  3651. Normally all of these processes are controlled
  3652. automatically by the operating system of your
  3653. computer. This makes things very much simpler
  3654. for you, but also inevitably limits the options
  3655. available for tailoring the display.
  3656. On the other hand the Amiga has some of the
  3657. most powerful and flexible graphics abilities
  3658. yet seen on a microcomputer. To exploit these,
  3659. MaxonBASIC allows a great deal of control over
  3660. various aspects of the Amiga´s operating
  3661. system, including Intuition. These are
  3662. explained in the Chapter 9 : Operating system
  3663. Support and the following section will only
  3664. cover the commands briefly to put their usage
  3665. into context.
  3666.  
  3667.  
  3668. A Word About Intuition
  3669.  
  3670. The Amiga range has an unusually sophisticated
  3671. system of screen handling through the Intuition
  3672. graphics environment. Intuition allows the user
  3673. to control the screen display via multiple
  3674. screens, multiple windows, graphic icons and
  3675. many other display features and options. These
  3676. can in turn be linked to, and controlled by,
  3677. the keyboard and mouse input devices.
  3678. Obviously, MaxonBASIC has to be able to let the
  3679. user access the power of the operating system
  3680. from within their own programs. However it
  3681. would be completely impractical and unwieldy to
  3682. provide special keywords for each of these
  3683. functions, and their possible permutations.
  3684. MaxonBASIC gives you a powerful and flexible
  3685. interface with all the Amiga operating system
  3686. calls by supplying a direct link via include
  3687. files derived directly from the standard
  3688. Commodore include files used by Assembler and C
  3689. programmers.
  3690. We will briefly describe the use of the include
  3691. files here and give an extended example in the
  3692. next section.
  3693. Once the include file is installed and
  3694. accessible to your own programs you will be
  3695. able to call any of these procedures by name,
  3696. as if they were keywords, and pass the required
  3697. parameters to them to get the result you want.
  3698. There are one or two pieces of bad news.
  3699. Firstly, some of the operating system calls are
  3700. detailed and fairly complicated and there is
  3701. not sufficient room in this book to give
  3702. details of what each one does.
  3703. Operating System Support (Chapter 9) is a
  3704. reference to all the various files provided,
  3705. but if you intend to take Amiga programming
  3706. more seriously, you will almost certainly have
  3707. to buy copies of the Amiga ROM Kernel Manuals
  3708. (even though these are targeted at C
  3709. programmers), never-the-less they are the final
  3710. word on using the Amiga operating system.
  3711.  
  3712. Text on Screen
  3713. When placing text on the screen, there are
  3714. really two broad classes of commands - those
  3715. that position the text on the screen, and those
  3716. that place the text at that position, and
  3717. control the way that it looks.
  3718. The position where text will appear as soon as
  3719. a PRINT or similar command is given is known as
  3720. the text cursor. The screen of the computer is
  3721. regarded as being divided into small squares,
  3722. each big enough to hold one letter, of which
  3723. there are eighty across and twenty down on a
  3724. regular high resolution screen.
  3725. The current horizontal position of this cursor
  3726. can be determined by using the function POS,
  3727. the vertical position by the function CSRLIN.
  3728. The text cursor can be re-located at any of
  3729. these text squares by the command LOCATE x,y
  3730. where x is the vertical position and y the
  3731. horizontal.
  3732. Either x or y can be omitted if their current
  3733. values are to remain unchanged (although the
  3734. commas that separate them must remain if x is
  3735. omitted). One other optional parameter makes
  3736. the cursor invisible or visible - see the
  3737. Command Reference. Try:
  3738.  
  3739.  
  3740. LOCATE 10,10
  3741. PRINT "Jim"
  3742. LOCATE 9,10
  3743. PRINT "Hello"
  3744.  
  3745.  
  3746. Which will produce the output:
  3747.  
  3748.  
  3749.      Hello
  3750.      Jim
  3751.  
  3752.  
  3753. Cursor positioning can also be achieved by
  3754. typing the two ´invisible characters´ - spaces
  3755. and tabs.
  3756. The keyword SPC(x) can be inserted in any PRINT
  3757. statement and it will cause the cursor to skip
  3758. x spaces before the specified text is
  3759. displayed.
  3760. TAB(x) used in a similar situation will cause
  3761. the text cursor to jump to column number x (if
  3762. x is less than the current position, the cursor
  3763. will move down by one screen line first). Note
  3764. also the use of STRING$ and SPACE$ which can be
  3765. used in PRINT statements.
  3766.  
  3767.  
  3768. PRINT SPC(10), "Hello"
  3769. PRINT TAB(10), "Hello"
  3770.  
  3771.  
  3772. will both produce the result:
  3773.  
  3774.  
  3775.           Hello
  3776.  
  3777.  
  3778. as will:
  3779.  
  3780.  
  3781. Let A$=SPACE$(10)
  3782. PRINT A$+"Hello"
  3783.  
  3784.  
  3785. Note that the command TAB(x) does not really
  3786. print a tab character but causes the cursor to
  3787. jump to the required spot on the screen. The
  3788. true tab character is designated by CHR$(9)
  3789. which can be used by many printers, and some
  3790. programs such as word processors, to trigger a
  3791. jump to preset tab positions. This is the
  3792. character usually returned by the tab key on
  3793. the keyboard.
  3794. With the cursor positioned where it is
  3795. required, text can be displayed by the PRINT
  3796. command. As we have seen even this has its own
  3797. parameters that control the subsequent
  3798. positioning of output - if text or a string is
  3799. terminated by a semi-colon future output begins
  3800. adjacent to that output. If it is terminated
  3801. with a comma the next item to be printed starts
  3802. at the next available x-column position on the
  3803. screen. The default tab width is 14 and this
  3804. can be changed using the WIDTH command.
  3805. If text reaches the end of a line it
  3806. automatically wraps around to the start of the
  3807. next. However it is possible to define a
  3808. smaller maximum line size by the use of the
  3809. WIDTH command.
  3810.  
  3811.  
  3812. WIDTH 20
  3813. PRINT "Hello Hello Hello Hello Hello"
  3814.  
  3815.  
  3816. will produce:
  3817.  
  3818.  
  3819. Hello Hello Hello He
  3820. llo Hello
  3821.  
  3822.  
  3823. Normally when the PRINT command is asked to
  3824. display data, such as a double precision
  3825. number, it shows it on screen in a way that
  3826. reflects its internal format. Often, however,
  3827. it is not desirable to have too many decimal
  3828. places displayed, or we may wish to manipulate
  3829. the display in some other way e.g. to add
  3830. currency symbols to the front of the data. The
  3831. PRINT USING command does all this and more and
  3832. is covered in detail in the Command Reference
  3833. section.
  3834. The WRITE keyword is also used to place data on
  3835. the screen but it differs from PRINT in that it
  3836. does not respond to any formatting commands.
  3837. Try this example:
  3838.  
  3839.  
  3840. REM An example of using WRITE
  3841. a=42 : b=a MOD 5 : c#=22/7
  3842. WRITE "The answer is "; a
  3843. WRITE b*5, c#
  3844.  
  3845.  
  3846. Run the program - is that what you expected?
  3847. Any strings that are printed will be enclosed
  3848. in quotes.
  3849. In practice WRITE is more useful when
  3850. debugging, or when producing disc files where
  3851. the internal format of the number needs to be
  3852. preserved. PRINT is of more value for the
  3853. screen display in most other cases because of
  3854. its extensive formatting control.
  3855. Finally, an important command for controlling
  3856. the text, and indeed graphics, display is CLS
  3857. which means ´clear screen´. This command will
  3858. also return the cursor to the top left hand
  3859. edge of the screen ready for printing new data.
  3860.  
  3861.  
  3862. CLI vs. Workbench - when is text not text
  3863.  
  3864. The Amiga comes supplied with a standard
  3865. character set which gives the only characters
  3866. available for printing text in CLI mode.
  3867. One of the main features of Workbench (and the
  3868. whole of the graphical aspect of the Amiga
  3869. operating system), on the other hand, is that
  3870. it is possible to use several different fonts
  3871. and text styles, such as italic or bold print,
  3872. on screen. These special font styles cannot be
  3873. handled in the same way as normal text - they
  3874. are in effect ´pictures of text´ that are drawn
  3875. on the screen. The ordinary MaxonBASIC commands
  3876. for displaying and manipulating text are not be
  3877. capable of manipulating them in the required
  3878. way, and instead your program will have to pass
  3879. commands through the OS interface header files.
  3880.  
  3881.  
  3882. Graphics
  3883.  
  3884.  
  3885.  
  3886. Two ways to produce graphics
  3887.  
  3888. There is more than one way to produce a picture
  3889. on your screen, but to appreciate the
  3890. difference between the various techniques
  3891. involves an understanding of how the screen
  3892. display memory works.
  3893. The image you see on the screen is made up of a
  3894. matrix of small dots known as pixels - in the
  3895. high resolution Amiga monochrome mode there are
  3896. (at least) 640 * 200 pixels which makes 128000
  3897. dots in total.
  3898. As with any form of data, if the computer is to
  3899. remember the image that is to be retained on
  3900. the screen it needs to put aside a certain
  3901. amount of memory for the task.
  3902. It is possible for sections of the screen to be
  3903. accessed directly, altered, moved, copied or
  3904. saved to disk.
  3905. Say that we have a screen with a simple graphic
  3906. image on it - one straight line. The program
  3907. that draws that line may be only one command
  3908. long and can be saved in a disk file that is
  3909. less than 1K in size. Every time we wish to
  3910. create that graphic image again the program can
  3911. almost instantly be run.
  3912. However if we wish to save the entire memory
  3913. image of that screen the file created will be
  3914. many times as large, and will probably still be
  3915. loading long after the first version has
  3916. finished.
  3917. Alternatively a detailed graphics image, say a
  3918. landscape scene, may require an complex program
  3919. of many hundreds of lines to re-create it. If
  3920. the screen picture is a digitised image of a
  3921. video picture or a creation from a computer art
  3922. package it may be practically impossible to
  3923. write a program that could reproduce it.
  3924. In this case a simple file that stores the
  3925. pixel data for the screen image will be the
  3926. most memory efficient and speedy system to use.
  3927. MaxonBASIC´s graphics keywords contain options
  3928. that will make it easy for you to choose
  3929. whichever of the above approaches best suit
  3930. your needs, or to mix them at will.
  3931. As with text the following keywords require a
  3932. means of signalling to the computer exactly
  3933. where you want the graphics to appear as well
  3934. as what graphic image it is to print. The
  3935. current position where graphics will appear is
  3936. known as the graphics cursor.
  3937. The following commands all produce certain
  3938. simple shapes on the screen at specified
  3939. positions. Their full range of permutations and
  3940. options are detailed in the Command Reference
  3941. chapter.
  3942. Movements of the graphics cursor can be
  3943. expressed in absolute coordinate terms like
  3944. that used to move the text cursor (although of
  3945. course the range of coordinates available
  3946. changes depending on the current screen
  3947. resolution). Alternatively it is sometimes
  3948. possible to express the required movement
  3949. relative to the current graphics cursor
  3950. position using STEP.
  3951. LINE is used to draw a line or a box on the
  3952. screen in a chosen line style and colour.
  3953. CIRCLE does the same for any size of arc,
  3954. circle or ellipse.
  3955.  
  3956. LINE (100, 100) - (200, 100)
  3957. will draw a line from the pixel position
  3958. (100,100) to the pixel position (200,100).
  3959. LINE and PAINT are used to draw shapes that are
  3960. filled by a specified colour or tile pattern.
  3961. The ability to rapidly and automatically fill
  3962. shapes with a given pattern, which can be
  3963. extremely complex, is one of the most powerful
  3964. features of the Amiga and can give a very
  3965. professional look to your programs if used with
  3966. restraint.;
  3967. PSET and PRESET both draw a pixel dot at the
  3968. specified position on the screen in the
  3969. specified colour. If the colour option is
  3970. omitted PSET will default to the current
  3971. foreground colour but PRESET will default to
  3972. the background colour. POINT is a complementary
  3973. command that will read the colour displayed at
  3974. specific pixel position.
  3975.  
  3976.  
  3977. Using Colours
  3978.  
  3979. The standard Amiga A500 computer is capable of
  3980. displaying a maximum of thirty-two colours at
  3981. once (without using EHB or HAM modes). The
  3982. current colours for printing and drawing can be
  3983. selected by the programmer from a list of 0-31,
  3984. detailed in the Command Reference section,
  3985. under COLOR.
  3986. The extra palette and colours of the Amiga 1200
  3987. and 4000 can be accessed from MaxonBASIC in two
  3988. ways: via the built-in PALETTE statement and
  3989. via the Graphics library LoadRGB32 and SetRGB32
  3990. functions.
  3991. COLOR (with apologies for the American
  3992. spelling) can be used to choose the colour with
  3993. which text is printed and the colour of the
  3994. background, or ´paper´, on which it is
  3995. displayed. When programming in CLI mode these
  3996. are the only options available.
  3997. PALETTE ;allows the programmer to change the
  3998. actual colours displayed on the screen. In this
  3999. way the displayed colours can be changed even
  4000. when, say, in the standard Workbench mode which
  4001. uses a screen display with only 4 colours (0 -
  4002. 3).
  4003. Try the following program:
  4004.  
  4005.  
  4006. REM $NOWINDOW    ´inhibit the standard BASIC
  4007. window
  4008. DEFINT a-z
  4009.  
  4010. REM $INCLUDE Graphics.bh ´Use Graphics for
  4011. WaitTOF
  4012. LIBRARY OPEN Ògraphics.libraryÓ
  4013.  
  4014. ´ Open a screen for our window
  4015. SCREEN 1,,,2,2     ´4 color high-res non-
  4016. interlaced screen
  4017. WINDOW 1,,,511,1 ´a "Works-Burger" window
  4018. (everything on it!)
  4019.  
  4020. ´ Draw three boxes in a triangular formation
  4021. FOR i = 1 TO 3
  4022.  x = 270   ´ set up co-ordinates for each box
  4023.  y = 25    ´ depends on the screen resolution!
  4024.  IF i = 2 THEN x = x - 75 : y = y + 65
  4025.  IF i = 3 THEN x = x + 75 : y = y + 65
  4026.  LINE (x, y) - STEP (100, 50), i, BF
  4027. NEXT i
  4028.  
  4029. ´ Cycle through all the colours
  4030.  
  4031. FOR red! = 0.0 TO 1.0 STEP 0.03125
  4032.  FOR green! = 0.0 TO 1.0 STEP 0.03125
  4033.      FOR blue! = 0.0 TO 1.0 STEP 0.03125
  4034.          ´ initialise each of the three colours
  4035. we use
  4036.          PALETTE 1, red!, green!, blue!
  4037.          PALETTE 2, blue!, red!, green!
  4038.          PALETTE 3, green!, blue!, red!
  4039.          WaitTOF
  4040.          WaitTOF
  4041.      NEXT blue!
  4042.  NEXT green!
  4043. NEXT red!
  4044.  
  4045.  
  4046. A colour that is altered by the PALETTE command
  4047. changes instantly on the display without
  4048. anything having to be redrawn. Many forms of
  4049. graphics effects and computer animation are
  4050. possible as a result.
  4051. For instance two different colour numbers can
  4052. be set by the PALETTE command to actually
  4053. display the same result on the screen. An image
  4054. drawn in one colour will therefore be invisible
  4055. against a background using the other. A new
  4056. PALETTE command that sets the image colour
  4057. number to a different setting will make that
  4058. image appear instantaneously.
  4059.   
  4060.   REM $INCLUDE Graphics.bh
  4061.   
  4062.   This  compiler meta-command  includes  all
  4063.   the   definitions,  functions   and   sub-
  4064.   programs  available in the standard  Amiga
  4065.   graphics  library.  We  do  this  to  gain
  4066.   access  to  the WaitTOF sub-program  which
  4067.   waits  for the Amiga to indicate that  the
  4068.   video-beam on the monitor has returned  to
  4069.   the top of the display. This allows us  to
  4070.   animate the colours on the display without
  4071.   them  flickering (caused by  changing  the
  4072.   colour  whilst  the beam was  passing  the
  4073.   point at which we changed it).
  4074.  
  4075.  
  4076. Pre-tokenised files
  4077.  
  4078.  
  4079.  
  4080. The next program we consider is going to use
  4081. the Amiga´s graphics library without using the
  4082. BASIC commands. It needs to include both the
  4083. Exec.bh and Graphics.bh files. When you are
  4084. developing such a program its a bit boring
  4085. waiting for the compiler to tokenise all the
  4086. constants in the include files every time you
  4087. make a change to your program; after all ,
  4088. these identifiers are going to be the same each
  4089. time. MaxonBASIC 3 enables you to pre-tokenise
  4090. these and then load the pre-tokenised
  4091. information when you compile your main program.
  4092. For the technical details of pre-tokenisation
  4093. see the end of the Compiler Section but here´s
  4094. how to use it in practice:
  4095. First create a file with just the includes that
  4096. we want like this
  4097.  
  4098.  
  4099. REM $INCLUDE Exec.bh
  4100. REM $INCLUDE Graphics.bh
  4101.  
  4102.  
  4103.                        
  4104. and save this out as abc_inc.bas using the Save
  4105. command from the Project menu. Select Tokenise
  4106.   from the Program menu and the pre-tokenised
  4107.  file abc_inc.t will be produced. To use this
  4108.   file select File sub-item from the Compiler
  4109.           item on the Settings menu.
  4110.                        
  4111.                        
  4112. Now click on Set by Tokens file and select the
  4113. abc_inc.t file with the file requester.
  4114. Now if you compile a program that uses these
  4115. include files, it will compile much more
  4116. quickly. Note that you will need to remove, or
  4117. comment out, the corresponding REM $INCLUDE
  4118. lines in your main program otherwise you´ll get
  4119. two copies!
  4120. When you have finished using a pre-tokenised
  4121. file you can select another one or select the
  4122. Token File line and use AX to remove an
  4123. existing one.
  4124.  
  4125.  
  4126. Example Graphics Library Program
  4127.  
  4128.  
  4129. Here´s a program that uses the Amiga´s graphics
  4130. library without using the BASIC commands. This
  4131. program should help you to understand the
  4132. principles of using the Amiga libraries.
  4133.  
  4134.  
  4135. DEFINT a-z
  4136.  
  4137. ´REM $INCLUDE Exec.bh
  4138. ´REM $INCLUDE Graphics.bh
  4139.  
  4140. LIBRARY OPEN "graphics.library"
  4141.  
  4142. CONST length% = 40, skew% = 15
  4143. CONST start% = 260, ystart% = 110
  4144. fb$ = "MaxonBASIC 3"
  4145.  
  4146. ´
  4147. ´SafeSetOutlinePen
  4148. `a backwards (<V39 graphics) compatible
  4149. SetOutlinePen
  4150. ´
  4151. SUB SafeSetOutlinePen(BYVAL w&, BYVAL c)
  4152.  STATIC junk&
  4153.  
  4154.  IF PEEKW(LIBRARY("graphics.library") +
  4155. lib_Version) >= 39 THEN
  4156.      junk& = SetOutlinePen&(w&, c)
  4157.  ELSE
  4158.      POKEB w& + AOlPen, c
  4159.      POKEW w& + RastPortFlags, PEEKW(w& +
  4160. RastPortFlags) OR AREAOUTLINE&
  4161.  END IF
  4162. END SUB
  4163.  
  4164. REM Sub-program to draw a 3-D box with a letter
  4165. SUB draw_box(BYVAL rp&, BYVAL x, BYVAL y, ch$)
  4166. STATIC ch_x, ch_y, junk&
  4167.  
  4168. REM Draw outline of a box
  4169.  SetAPen rp&, 0  ´ set foreground pen to
  4170. background color
  4171.  junk& = AreaMove(rp&, x, y)
  4172.  junk& = AreaDraw(rp&, x + skew, y - skew)
  4173.  junk& = AreaDraw(rp&, x + length + skew, y -
  4174. skew)
  4175.  junk& = AreaDraw(rp&, x + length + skew, y +
  4176. length - skew)
  4177.  junk& = AreaDraw(rp&, x + length, y + length)
  4178.  
  4179.  junk& = AreaDraw(rp&, x, y + length)
  4180.  junk& = AreaEnd(rp&)
  4181.  
  4182. REM Now draw 3 lines to complete 3-D box
  4183.  SetAPen rp&, 1  ´ select standard pen
  4184.  Move rp&, x, y
  4185.  Draw rp&, x + length, y
  4186.  Draw rp&, x + length + skew, y - skew
  4187.  
  4188.  Move rp&, x + length, y + length
  4189.  Draw rp&, x + length, y
  4190.  
  4191. REM Draw the letter text, centred in the box
  4192.  ch_x = TextLength&(rp&, SADD(ch$), LEN(ch$))
  4193.  ch_y = PEEKW(rp& + TxHeight)
  4194.  Move rp&, x + (length - ch_x) / 2, y + (length
  4195. + ch_y) / 2
  4196.  Text rp&, SADD(ch$), LEN(ch$)
  4197. END SUB
  4198.  
  4199. REM The main program
  4200.  
  4201. ´force the BASIC runtime library to initialise
  4202. TmpRas and
  4203. ´AreaInfo in the default window´s RastPort (!)
  4204. AREAFILL
  4205.  
  4206. SafeSetOutlinePen WINDOW(8), 1 ´set the outline
  4207. pen colour
  4208.  
  4209. draw_box WINDOW(8), xstart, ystart, "B"
  4210. draw_box WINDOW(8), xstart + 7 * length / 6,
  4211. ystart, "C"
  4212. draw_box WINDOW(8), xstart + 7 * length / 12,
  4213. ystart - 7 * length / 6, "A"
  4214.  
  4215. fb_width = TextLength&(WINDOW(8), SADD(fb$),
  4216. LEN(fb$))
  4217. fb_height = PEEKW(WINDOW(8) + TxHeight)
  4218. fb_x = xstart + (13 * length \ 6 + skew -
  4219. fb_width) \ 2
  4220. fb_y = ystart + length + fb_height * 3 \ 2
  4221.  
  4222. REM Display picture title
  4223. Move WINDOW(8), fb_x, fb_y
  4224. Text WINDOW(8), SADD(fb$), LEN(fb$)
  4225.  
  4226. END
  4227.  
  4228.  
  4229. Now let´s see how it´s done É
  4230. First of all, what are we trying to draw?
  4231. Answer: three 3-dimensional boxes, with letters
  4232. inside them and a title below all this. How are
  4233. we going to do the boxes?
  4234.  
  4235. We have to draw 3 boxes, all the same (except
  4236. for the letter inside it), so it makes sense to
  4237. have a sub-program to draw one box. To make a
  4238. box, we could just draw 9 lines but there are
  4239. several graphics library call to help us out É
  4240. The graphics library functions AreaMove,
  4241. AreaDraw and AreaEnd are used to define the
  4242. vertices of the polygon we want to fill. Look
  4243. at the box in Figure 3.1, formed by points 1,
  4244. 2, 3, 4, 5, and 6 - this is a closed polygon
  4245. and we could therefore draw it with AreaDraw.
  4246. What are the points? Well, if point 1 is (x,y)
  4247. and the length of each side of the box is
  4248. length and the depth, measured vertically and
  4249. horizontally, is skew then the points are as
  4250. follows:
  4251.  
  4252. Point 1 :(x, y)
  4253. Point 2 :(x+skew, y-skew)
  4254. Point 3 :(x+length+skew, y-skew)
  4255. Point 4 :(x+length+skew, y+length-skew)
  4256. Point 5 :(x+length, y+length)
  4257. Point 6 :(x, y+length)
  4258.  
  4259. So, to draw this polygon we must set up the 6
  4260. points (we AreaMove to the first point,
  4261. AreaDraw to the next five, then mark that we´re
  4262. done with AreaEnd):
  4263.  
  4264.  
  4265. REM Draw outline of a box
  4266.  junk& = AreaMove(rp&, x, y)
  4267.  junk& = AreaDraw(rp&, x + skew, y - skew)
  4268.  junk& = AreaDraw(rp&, x + length + skew, y -
  4269. skew)
  4270.  junk& = AreaDraw(rp&, x + length + skew, y +
  4271. length - skew)
  4272.  junk& = AreaDraw(rp&, x + length, y + length)
  4273.  junk& = AreaDraw(rp&, x, y + length)
  4274.  junk& = AreaEnd(rp&)
  4275.  
  4276.  
  4277. To draw this polygon we should first set up the
  4278. colour index of the fill and the border; this
  4279. is done with SetAPen (for the fill) and the
  4280. curious SafeSetOutlinePen sub program (which
  4281. sets the outline colour, which we´ll
  4282. investigate later, but ignore for the momentÉ).
  4283. SetAPen simply sets the Amiga´s foreground pen
  4284. (which is historically known as the A-Pen.
  4285.   
  4286.   The Amiga has a second pen, the background
  4287.   pen,  which  is known as the B-Pen  -  not
  4288.   surprisingly  the sub-program  SetBPen  is
  4289.   used  to  set it! Historically the outline
  4290.   pen is also known as the O-Pen.
  4291. In order to call the SetAPen sub-program we
  4292. also need a ´RastPort pointer´; the internal
  4293. details of this aren´t important to us at the
  4294. moment, but a quick look in the Command
  4295. Reference tells us that the WINDOW(8) function
  4296. gives us a pointer to the RastPort for the
  4297. current window.
  4298.   
  4299.   Internally  the Amiga graphics library  is
  4300.   capable  of  drawing into many windows  at
  4301.   the  same  time  (since  the  Amiga  is  a
  4302.   multitasking  machine),  so  for  each  of
  4303.   these   drawing  operations  it  needs   a
  4304.   drawing  context;  the  RastPort  is  this
  4305.   context   information  (it  contains   the
  4306.   current  A  pen  and B  pen  settings  for
  4307.   example).  A  RastPort is associated  with
  4308.   every  window in the system, every screen,
  4309.   and   any   other  RastPorts   which   the
  4310.   programmer creates.
  4311. Now, drawing the polygon hasn´t given us our 3D
  4312. box yet - we need to add lines from point 7 to
  4313. point 1, from point 7 to point 3 and from point
  4314. 7 to point 5 (see Figure 3.1). We need another
  4315. graphics library call to do this (we could use
  4316. the BASIC LINE command but since we´re trying
  4317. to do this without using the BASIC routinesÉ
  4318. the two calls which we need are Move (to move
  4319. the drawing position), and Draw (draw a line
  4320. from the current drawing position).
  4321.  
  4322.  
  4323. REM Now draw 3 lines to complete 3-D box
  4324.  SetAPen rp&, 1  ´ select standard pen
  4325.  Move rp&, x, y
  4326.  Draw rp&, x + length, y
  4327.  Draw rp&, x + length + skew, y - skew
  4328.  
  4329.  Move rp&, x + length, y + length
  4330.  Draw rp&, x + length, y
  4331.  
  4332.  
  4333. Again we need to select the correct pen for
  4334. drawing, so SetAPen is again used to select the
  4335. pen we need (pen 1 this time).
  4336.   
  4337.   The  pen  numbers used on the  Amiga  from
  4338.   Workbench  2.0  onwards are  not  strictly
  4339.   fixed  (as we are using them), the correct
  4340.   procedure  is  to  call  the  OS   routine
  4341.   GetScreenDrawInfo which returns a complete
  4342.   description   of   the  user´s   preferred
  4343.   graphic  context (as set  by  the  various
  4344.   Preferences editors), and then extract the
  4345.   desired  information; for simplicity  this
  4346.   has been skipped here.
  4347. So, we´ve drawn a 3D box; now we have to put a
  4348. character in it. To do this we use the graphics
  4349. library Text sub-program; this draws a
  4350. character at the current graphic location (as
  4351. set by Move).
  4352. We also need a bit of arithmetic to work out
  4353. where to place this character so that it
  4354. appears in the middle of our box. First we need
  4355. to know the width and height of a character -
  4356. can the graphics library help? There´s a
  4357. routine called TextLength that returns the
  4358. number of pixels needed to enclose a text
  4359. string horizontally:
  4360.  
  4361.  
  4362.  ch_x = TextLength&(rp&, SADD(ch$), LEN(ch$))
  4363.  
  4364.  
  4365. The TextLength function takes three parameters:
  4366. rp& - the now familiar RastPort pointer, a
  4367. pointer to the start of the string ch$ (for
  4368. which we use the SADD function, this converts a
  4369. BASIC string into a pointer suitable for the
  4370. operating system), and LEN(ch$) - the length of
  4371. the string.
  4372. Having found the number of pixels across our
  4373. text will be, we now need to find its height;
  4374. this is stored in the RastPort pointed to by
  4375. rp&. To find the value, we have to PEEK at the
  4376. word in the RastPort structure at the TxHeight
  4377. offset, hence:
  4378.  
  4379.  
  4380.  ch_y = PEEKW(rp& + TxHeight)
  4381.  
  4382.  
  4383. So now we have ch_y as the height of the string
  4384. and ch_x as the width. To put the string in the
  4385. centre of the front face of the box (the face
  4386. is length wide by length high, remember), we
  4387. need to put the bottom left of the character at
  4388. co-ordinate (x+length/2-ch_x/2,
  4389. y+length/2+ch_y/2) where (x,y) is the top left
  4390. of the front face. Look at Figure 3.1 to see
  4391. that this is right. Keep looking!
  4392. So, this should do it:
  4393.  
  4394.  
  4395.  Move rp&, x + (length - ch_x)/2, y + (length +
  4396. ch_y)/2
  4397.  
  4398.  
  4399. Then having moved to the correct co-ordinates
  4400. we actually have to draw the text:
  4401.  
  4402.  
  4403.  Text rp&, SADD(ch$), LEN(ch$)
  4404.  
  4405.  
  4406. Notice that the parameters passed to the Text
  4407. sub-program are identical to those passed to
  4408. TextLength.
  4409. That effectively completes the draw_box sub-
  4410. program. Notice that we have passed the
  4411. RastPort (rp&), the top left (x, y) co-
  4412. ordinates as parameters and also the letter
  4413. that is to be contained in the box is a
  4414. parameter (the third one).
  4415. Now we´ve completed the draw_box sub-program we
  4416. need to write our main program, obviously the
  4417. main thing for this to do is to draw the three
  4418. boxes and the title, however first we need to
  4419. do some extremely important setup:
  4420.  
  4421. ´force the BASIC runtime library to initialise
  4422. TmpRas and
  4423. ´AreaInfo in the default window´s RastPort (!)
  4424. AREAFILL
  4425. The AREAFILL command is a standard BASIC
  4426. command which is normally used for doing very
  4427. much the same sort of thing as we did with
  4428. AreaMove et al. However when used in this
  4429. special way (with no parameters) on the default
  4430. window it forces several internal things to be
  4431. set up in the RastPort which are not normally
  4432. set up until a fill occurs (to save memory).
  4433. Since we´re not using the BASIC fill commands
  4434. we must ask BASIC to set up these things in
  4435. advance for us.
  4436.   
  4437.   The  elements  within the  RastPort  which
  4438.   must  be  set  are the TmpRas  (a  second,
  4439.   temporary,   RastPort)  and  an   AreaInfo
  4440.   array.  The first of these is used  whilst
  4441.   the  graphics  library  is  rendering  the
  4442.   resulting polygon, the latter is used  for
  4443.   storing the vertices of the polygon  until
  4444.   the  AreaEnd sub-program is called  (BASIC
  4445.   normally  initialises  the  AreaInfo  with
  4446.   enough  space  for 20 vertices  -  if  you
  4447.   exceed  this any additional vertices  will
  4448.   be ignored).
  4449. The other piece of set up which we ignored
  4450. until now was setting up the colour of the
  4451. outline used for the polygons. To do this we
  4452. need a bit of chicanery involving the RastPort,
  4453. together with some graphics library version
  4454. dependent code:
  4455.  
  4456.  
  4457. SUB SafeSetOutlinePen(BYVAL w&, BYVAL c)
  4458.  STATIC junk&
  4459.  
  4460.  IF PEEKW(LIBRARY("graphics.library") +
  4461. lib_Version) _
  4462.  
  4463.    >= 39 THEN
  4464.      junk& = SetOutlinePen&(w&, c)
  4465.  ELSE
  4466.      POKEB w& + AOlPen, c
  4467.      POKEW w& + RastPortFlags, _
  4468.          PEEKW(w& + RastPortFlags) OR
  4469. AREAOUTLINE&
  4470.  END IF
  4471. END SUB
  4472. É
  4473. SafeSetOutlinePen WINDOW(8), 1 ´set the outline
  4474. pen color
  4475.  
  4476.  
  4477. The first line checks the version of the
  4478. graphics library which is in use, the function
  4479. LIBRARY("graphics.library") finds the location
  4480. of the library base pointer, to this we add the
  4481. offset to the version number word (lib_Version)
  4482. and PEEK the word at the location. In this case
  4483. we need a graphics library version after V39
  4484. (Workbench 3); in this version an additional
  4485. function, SetOutlinePen was added which sets
  4486. the outline pen for us.
  4487.  
  4488.  
  4489. IF
  4490. PEEKW(LIBRARY("graphics.library")+lib_Version)>
  4491. =39 THEN
  4492.  
  4493.  
  4494. If we find we don´t have a new enough graphics
  4495. library, then we fall back to setting the
  4496. outline pen in a manner which works on older
  4497. versions of the operating system:
  4498.  
  4499.  
  4500. POKEB w& + AOlPen, c
  4501. POKEW w& + RastPortFlags, _
  4502.  PEEKW(w& + RastPortFlags) OR AREAOUTLINE&
  4503.  
  4504.  
  4505. Here we first set the outline pen by POKEing
  4506. the byte at the AOlPen (Area Outline Pen)
  4507. offset in the RastPort (w&), then we need to
  4508. tell the graphics library that it should render
  4509. the pen when drawing the areas (as opposed to
  4510. not drawing an outline around the polygon at
  4511. all). To do this we have to set the AREAOUTLINE
  4512. flag in the RastPort´s Flags; first we PEEK the
  4513. existing value (since we don´t want to disturb
  4514. any of the current bits which are set), OR in
  4515. the value of the AREAOUTLINE flag, then POKE
  4516. the result back.
  4517. Finally we call the SafeSetOutlinePen sub-
  4518. program in the main body of our program to set
  4519. the pen, as you can see the sub-program nicely
  4520. hides all of the complexity of setting the
  4521. outline pen correctly on all OS versions,
  4522. making for a clearer, easier-to-understand
  4523. program.
  4524. Now that we´ve (finally!) completed all our
  4525. setup, all that remains is to call draw_box 3
  4526. times (for 3 boxes) and then to write some text
  4527. underneath the whole thing. Again, we´ll use
  4528. Text to write the message and do a little
  4529. arithmetic to make sure that the text message
  4530. is centred under the boxes:
  4531.  
  4532.  
  4533. draw_box WINDOW(8), xstart, ystart, "B"
  4534.  
  4535. draw_box WINDOW(8), xstart + 7 * length / 6,
  4536. ystart, "C"
  4537. draw_box WINDOW(8), xstart + 7 * length / 12,
  4538. ystart - 7 * length / 6, "A"
  4539.  
  4540. fb_width = TextLength&(WINDOW(8), SADD(fb$),
  4541. LEN(fb$))
  4542. fb_height = PEEKW(WINDOW(8) + TxHeight)
  4543. fb_x = xstart + (13 * length \ 6 + skew -
  4544. fb_width) \ 2
  4545. fb_y = ystart + length + fb_height * 3 \ 2
  4546.  
  4547.  
  4548. We hope that has given you some insight into
  4549. using the Amiga libraries - it is really not as
  4550. daunting as it first looks and well worth the
  4551. initial effort!
  4552. Of course, if you find the library functions
  4553. and sub-programs difficult to remember or
  4554. clumsy to use you can always re-write and re-
  4555. name them.
  4556.   
  4557.   When  using  the Amiga´s operating  system
  4558.   directly   it   is   essential   to   have
  4559.   documentation on the various  calls;  this
  4560.   is all contained in the ROM Kernel Manuals
  4561.   (RKMs). Although these are written  for  C
  4562.   and  Assembler  programmers,  learning   a
  4563.   little C is enough understand much of what
  4564.   the   RKMs   cover.   Without   the   RKMs
  4565.   programming  the  Amiga at  the  operating
  4566.   system level is almost impossible.
  4567.  
  4568.  
  4569. Blitting
  4570.  
  4571. There is an alternative approach to producing
  4572. graphics effects which relies on using keywords
  4573. which directly access and manipulate areas of
  4574. the screen display memory. Moving or copying
  4575. such areas of memory, or switching one area of
  4576. screen memory with another, can be used to
  4577. produce outstanding animation effects. Moving
  4578. bits of screen memory around is known as
  4579. blitting (the word stems from bit block
  4580. transfer).
  4581. GET and PUT allow the program to pick up a
  4582. specified rectangular block from the screen
  4583. display and place it in a different position on
  4584. the screen. An array of the appropriate size
  4585. has to be specified for storing the data. A
  4586. block that is picked up by GET is not
  4587. automatically obliterated from the screen but
  4588. merely copied into an array.
  4589. Several arrays can be filled using the GET
  4590. command. These can also be copied to a
  4591. sequential disk file in the same way that any
  4592. array would be, ready for subsequent re-
  4593. loading. In this way you could prepare a
  4594. program that contained several digitised
  4595. images, for example, that can be used for
  4596. illustrations, or could be subsequently PUT
  4597. into the same position to produce an animated
  4598. effect.
  4599. In the past these techniques have been felt to
  4600. consume too much memory to allow their frequent
  4601. use in micro-computer programs, but most Amiga
  4602. machines have lots of RAM to spare and can hold
  4603. many such arrays at once, leaving you free to
  4604. produce incredibly sophisticated effects with
  4605. ease.
  4606. The PUT command has several options that allow
  4607. different graphics and animation effects to be
  4608. achieved using the techniques described in
  4609. Using Logical Operators in Arithmetic where an
  4610. example of GET and PUT was also given. These
  4611. options are detailed in the Command Reference
  4612. section. Trial and error is also a good way of
  4613. seeing how these routines work in practice -
  4614. experiment with PUTting picture blocks onto a
  4615. blank screen and onto a screen that already
  4616. contains a detailed image to see how different
  4617. effects can be achieved (people using a colour
  4618. display will find a lot more interesting
  4619. effects are possible than with a monochrome
  4620. monitor).
  4621.  
  4622.  
  4623. Windows
  4624.  
  4625. Anyone who has had experience of using the
  4626. Amiga will quickly learn what windows are, what
  4627. they can do and how they can give your programs
  4628. a professional and polished air. Many languages
  4629. will only allow you to use windows by making
  4630. rather complicated calls to the Intuition
  4631. system.
  4632. MaxonBASIC however comes with a comprehensive
  4633. selection of built-in commands that are
  4634. designed to make the process of calling windows
  4635. as easy and as fluent as possible. The built-in
  4636. commands are fully documented under the WINDOW
  4637. keyword, in the Command Reference section and
  4638. we will give an example here.
  4639. WINDOW is a remarkably compact keyword
  4640. requiring you only to provide several
  4641. parameters such as the size, position, nature
  4642. and contents of the window and MaxonBASIC and
  4643. Intuition do all of the work of drawing the
  4644. image on screen etc.
  4645. Note that when using multiple windows each is
  4646. referred to by a specific identification number
  4647. in a way that parallels those required for
  4648. managing several disk files at once.
  4649.  
  4650.  
  4651. DEFINT A-Z
  4652.  
  4653. ´ get the width & height of the free BASIC
  4654. window
  4655. ww = WINDOW(2)
  4656. wh = WINDOW(3)
  4657.  
  4658. ´ draw an ellipse using pen 1 in the free BASIC
  4659. window
  4660. CIRCLE (ww \ 2, wh \ 5), ww \ 3, 1,,, (wh / ww
  4661. / 2)
  4662.  
  4663. ´ fill from the centre using pen 3, outwards to
  4664. pen 1
  4665. PAINT (ww \ 2, wh \ 5), 3, 1
  4666.  
  4667. ´ open another window, id number 2
  4668. WINDOW 2, "Another window", (ww \ 4, wh \ 2) -
  4669. (ww * 3 \ 4, wh)
  4670.  
  4671. ´Print something novel in window 2
  4672. PRINT "Welcome to MaxonBASIC 3!"
  4673.  
  4674.  
  4675.  
  4676.  
  4677. Talking to the Outside World
  4678.  
  4679. It is probably true to say that taking in input
  4680. and producing output, are the most important
  4681. jobs that a computer program has to do.
  4682. There is very little value to line after line
  4683. of complex calculation or data manipulation
  4684. unless at the end of it all an answer is
  4685. displayed on a page or the screen. We have
  4686. already seen that without a PRINT command most
  4687. programs are functionally useless.
  4688. Similarly it is certainly true that, with the
  4689. exception of some graphics demos and the likes,
  4690. most programs are useless unless they take some
  4691. information from the user, a keypress or menu
  4692. choice at the very least, or from the outside
  4693. world via equipment such as a temperature
  4694. sensor.
  4695. We have already looked at what are perhaps the
  4696. two most fundamental commands that deal with
  4697. input and output of information, INPUT and
  4698. PRINT. There are however many different options
  4699. that exist to complement or modify these basic
  4700. keywords.
  4701.  
  4702.  
  4703. Input and Output
  4704.  
  4705. There are several possible sources of
  4706. information, not just data but also commands
  4707. from the user, that are available for your
  4708. program to act upon - these include the
  4709. keyboard and mouse, files held on disk, and the
  4710. computer´s hardware ports. The options
  4711. available for output include again the hardware
  4712. ports, disk files, the speaker, a printer and,
  4713. of course, the screen.
  4714. The operating system of the Amiga computer
  4715. itself can also often be looked upon as an
  4716. external source of information for your
  4717. programs as it acts as an intermediate between
  4718. BASIC and the hardware.
  4719. The operating system is a special master
  4720. program that is in charge of everything the
  4721. computer does. It recognises what key you are
  4722. pressing on your keyboard, it knows how to make
  4723. the disk drives spin round when required and so
  4724. on. It is this master program that also
  4725. contains all of the graphics routines.
  4726. The operating system keeps charge of the date
  4727. and time clock that is available through
  4728. commands such as DATE$, it is the operating
  4729. system that provides information on the status
  4730. of the disk drive (such as which files are
  4731. present), it is the operating system that
  4732. detects when many hardware devices signal an
  4733. error (such as disk missing from the drive).
  4734. All of these items of information can be used
  4735. by your own programs to control which command
  4736. lines and subroutines are to be executed.
  4737. Similarly when outputting data or instructions,
  4738. the operating system may be the immediate
  4739. receiver of the information you send. For
  4740. instance when sending graphics commands your
  4741. programs will be talking to the graphics
  4742. library to get the desired effects rather than
  4743. attempting to manipulate the screen display
  4744. directly.
  4745. Each of these input/output ´targets´ can be
  4746. accessed by special related keywords or pre-
  4747. defined library routines.
  4748.  
  4749.  
  4750. The Keyboard, Joystick and Mouse
  4751.  
  4752. We have already looked at how the INPUT command
  4753. works but although this is really a very simple
  4754. keyword there are a few important options
  4755. available.
  4756. You have the ability to suppress the question
  4757. mark the command displays by the use of a comma
  4758. instead of a semi-colon after the keyword.
  4759. The response given by the user must of course
  4760. match the type of variable expected by the
  4761. INPUT keyword or the user will get the message
  4762. Redo from start. This is a wonderfully
  4763. ambiguous message and means ´redo the current
  4764. entry from the start´ (as if you could do
  4765. anything else) rather than ´redo every input
  4766. question you may have just been asked´. Strings
  4767. entered as input need not be placed within
  4768. quotes, and as long as they are not so enclosed
  4769. the quote character - " - can be used as part
  4770. of the string (but obviously not in the first
  4771. character position).
  4772. Several items of data can be requested and
  4773. entered in one go, although the number and type
  4774. of the data entries must again match those
  4775. required. In both the program line and during
  4776. the entry process all items must be separated
  4777. by commas.
  4778. LINE INPUT will read an entire line of data,
  4779. until terminated by a carriage return, and
  4780. assigns it to one string variable. It does this
  4781. even when the information is separated into
  4782. sections by commas which would have been taken
  4783. to be data separators by the INPUT command.
  4784. If you have a line:
  4785.  
  4786.  
  4787. INPUT A$, B$, C$
  4788.  
  4789.  
  4790. and the user enters:
  4791.  
  4792.  
  4793. Bob Smith, 10 New Road, London
  4794.  
  4795.  
  4796. then A$ will equal Bob Smith
  4797. Whereas if you had a line:
  4798.  
  4799.  
  4800. LINE INPUT A$
  4801.  
  4802.  
  4803. which is given the same input A$ would be given
  4804. the value of:
  4805.  
  4806.  
  4807. Bob Smith, 10 New Road, London
  4808.  
  4809.  
  4810. LINE INPUT is particularly useful when reading
  4811. an ASCII file from disk, e.g. a file created by
  4812. the MaxonBASIC editor. Each line can be
  4813. extracted from the file in turn and displayed,
  4814. printed, or both regardless of whether it
  4815. contains commas or any other form of
  4816. punctuation.
  4817. Both INPUT and LINE INPUT allow the user to
  4818. edit the data while it is being entered to make
  4819. corrections by using the Backspace key to
  4820. delete data already entered.
  4821. A closely related command is INKEY$ which reads
  4822. the keyboard to see if any key, or combination
  4823. of keys, has been pressed. If no key has been
  4824. pressed an empty or null string is returned.
  4825. The important differences from INPUT are that
  4826. only one character value is returned at a time,
  4827. and that the program does not have to wait for
  4828. the user to hit Return before it can start to
  4829. respond to the key.
  4830. If a key is pressed which is defined to produce
  4831. a string of text, such as one of the function
  4832. keys, INKEY$ will only take one character from
  4833. the string every time the command is made.
  4834. INKEY$ is often used in conjunction with
  4835. logical loops such as DOÉLOOP to wait for a
  4836. response from the user e.g.
  4837.  
  4838.  
  4839. SUB Wait
  4840.  PRINT "Press any key to continue"
  4841.  DO
  4842.  LOOP UNTIL INKEY$<>""
  4843. END SUB
  4844.  
  4845.  
  4846.   
  4847.   Note   that   this  is   an   example   of
  4848.   particularly    bad   Amiga   programming!
  4849.   Because  of the way we´ve used INKEY$  the
  4850.   computer  is being forced to Òbusy  waitÓ,
  4851.   i.e.   we´re  keeping  it  tied  up  doing
  4852.   nothing  which  means that other  programs
  4853.   can´t have as much time to execute. A much
  4854.   better   method  is  to  use   the   SLEEP
  4855.   statement which puts your program to sleep
  4856.   until an event of some form arrives.
  4857. The INPUT$(x) command is like a hybrid between
  4858. INPUT and INKEY$ - it reads x number of
  4859. keypresses from the keyboard and passes them
  4860. directly to the program. This command is
  4861. particularly useful as it allows a long string
  4862. to be entered from the keyboard which need not
  4863. be terminated by Return, and which can even
  4864. contain, CHR$(13), in the middle somewhere.
  4865. Control of the mouse is via the keyword MOUSE
  4866. This is very simple to use and there is a good
  4867. example of its use in the Command Reference
  4868. section.
  4869. The various joystick ports can be read by the
  4870. following keywords.
  4871.  
  4872.  
  4873. STICK(n)
  4874. is a function that returns a reading of the
  4875. position of a joystick. The information the
  4876. program requires from this function is
  4877. signalled by the value of n which is passed.
  4878. This can be 0 - 3 and the values returned
  4879. respectively are the x position of joystick 1,
  4880. the y position of joystick 1, the x position of
  4881. joystick 2 and the y position of joystick 2.
  4882. The values returned are -1 (Left/Up), 0
  4883. (Centre) and 1 (Right/Down).
  4884.  
  4885.  
  4886. STRIG(n)
  4887. returns a value as to whether any of the
  4888. joystick buttons has been pressed; n can be
  4889. from 0 to 3. Respectively these signal whether
  4890. the button on joystick 1 has been pressed since
  4891. the last STRIG(0) command, whether button is
  4892. currently pressed, whether button on joystick 2
  4893. has been pressed since the last STRIG(2)
  4894. command, whether button is currently pressed.
  4895.  
  4896.  
  4897. The Printer
  4898.  
  4899. The printer is not a standard peripheral for
  4900. the Amiga computer, but it is so common for
  4901. people to buy one that it is given full support
  4902. from the operating system and from within
  4903. MaxonBASIC.
  4904. The commands used for producing output on the
  4905. printer are in many ways identical to those for
  4906. laying out text on the screen, with the obvious
  4907. exceptions that it is usually only possible to
  4908. move the printhead down the page (some printers
  4909. have a limited reverse paper feed option but it
  4910. is rarely effective over more than a line or
  4911. two) and that text can be overprinted, but not
  4912. erased.
  4913. The LOCATE command is therefore of no use, and
  4914. steps down the page are usually accomplished by
  4915. sending a series of carriage returns, by
  4916. sending special codes that force a printer
  4917. ´line feed´ (most machines allow you to set the
  4918. line feed to be of variable height) or that
  4919. cause the printer to perform a ´vertical tab´
  4920. jump. If your printer supports either of the
  4921. latter two options they will be explained more
  4922. fully in the accompanying documentation
  4923. Some printers, especially those that are
  4924. capable of different print pitches, can also
  4925. use very many more characters across the page
  4926. than is possible on the screen.
  4927. The LPOS keyword returns the value for what the
  4928. computer feels should be the horizontal
  4929. position of the print head on the paper, based
  4930. on how many characters have been sent to the
  4931. printer since the last carriage return. The
  4932. situation can actually arise where the computer
  4933. gets this wrong, e.g. if the printer head was
  4934. left in an unusual position by a previous
  4935. program. The keyword is also unable to keep
  4936. track of what effect, if any, the tab character
  4937. is producing on the printer (the size of tab
  4938. jumps can be defined on most machines) but on
  4939. the whole the information returned should be
  4940. reliable.
  4941. LPOS is typically used for testing whether
  4942. there is enough room on the line remaining to
  4943. send the next word you wish to print. If there
  4944. is not, a carriage return/line feed can be sent
  4945. first ensuring that no words are broken in
  4946. half.
  4947. Because of the relative lack of control you
  4948. have over this feature there is no keyword for
  4949. returning the vertical position of the print
  4950. head.
  4951. As with text printing on screen the WIDTH
  4952. LPRINT command can be used to set the maximum
  4953. width of the printed display. After the
  4954. specified number of characters have been sent a
  4955. new line is automatically started.
  4956.  
  4957.  
  4958. Sound
  4959.  
  4960. MaxonBASIC provides many ways of handling sound
  4961. on your Amiga computer. First of all, here is
  4962. some (very) simple keywords.
  4963. We have met BEEP already and there is really
  4964. nothing more to say about it as it is a very
  4965. simple command. It is most useful as a means of
  4966. signalling an error or attracting attention to
  4967. a message in your program. It is worth noting
  4968. that a similar effect can be achieved by the
  4969. command:
  4970.  
  4971. PRINT CHR$(7)
  4972.  
  4973. This can be useful when you have written a
  4974. routine that reads a series of ASCII numbers,
  4975. say from a file held on disk, and prints them
  4976. onto the screen. ASCII number 7 can be held
  4977. within the file to signal the end of a
  4978. particular message or something like that.
  4979. Although we´ve listed BEEP as a sound command
  4980. on the Amiga as standard it is mute! Never-the-
  4981. less it is usually thought of as a sound
  4982. command.
  4983. The command SOUND is only slightly more
  4984. sophisticated. It allows the pitch and duration
  4985. of the note to be varied, and is detailed in
  4986. the Command Reference chapter.
  4987. The WAVE command is a useful complement to the
  4988. keyword SOUND as it allows the type of noise
  4989. that is to be produced to be controlled by
  4990. defining the waveform and envelope of the
  4991. noise. This is again explained in more detail
  4992. in the Command Reference section.
  4993.  
  4994.  
  4995. The Timer
  4996.  
  4997. The timer is not a true physical device on the
  4998. Amiga computer, but the effect of one is
  4999. simulated by the operating system as a
  5000. constantly active background task. As long as
  5001. the machine is not turned off or reset the
  5002. current date and time can be read or reset
  5003. through MaxonBASIC.
  5004.  
  5005. DATE$ and TIME$ are used as functions to return
  5006. the current value of the ´clock´ settings; the
  5007. values are returned as specially formatted
  5008. strings.
  5009.  
  5010. TIMER is a function that returns the number of
  5011. seconds since midnight. The returned value is a
  5012. single-precision numeric value so two calls to
  5013. the TIMER function can be used to time a given
  5014. part of the program with much more accuracy
  5015. than using the TIME$ command (TIME$ returns
  5016. information as a specially formatted string).
  5017. TIMER´s accuracy is to the 50th of a second,
  5018. whereas TIME$´s accuracy is 1 second.
  5019. If you have a program that wants to do
  5020. something regularly, may be to update a status
  5021. display you can use the ONÉTIMER statement.
  5022. Here´s a rather silly example:
  5023.  
  5024.  
  5025. ON TIMER(2) GOTO timer_handler
  5026. TIMER ON
  5027.  
  5028. FOR i=1 TO 1000
  5029.  PRINT i
  5030. NEXT i
  5031.  
  5032. STOP
  5033.  
  5034. timer_handler:
  5035.  PRINT "hello"
  5036.  RETURN
  5037.  
  5038.  
  5039. Here every 2 seconds (the number in brackets in
  5040. the ONÉTIMER statement, the timer_handler
  5041. routine will be executed. The TIMER ON
  5042. statement starts the timer off; if you want to
  5043. stop a timer for a while (perhaps because you
  5044. need to do something urgently like download a
  5045. file) you can do this with the TIMER OFF
  5046. command; use TIMER ON to switch it back on
  5047. again.
  5048. i.file handling;
  5049.  
  5050.  
  5051. Managing Files
  5052.  
  5053. MaxonBASIC provides a complete suite of
  5054. commands to allow the programmer to access and
  5055. control the filing system. All large utility
  5056. programs you write should employ these commands
  5057. to allow the user to best organise the layout
  5058. of files on the disk from within your program,
  5059. particularly if they may need to create room
  5060. for data by erasing or copying some of the
  5061. existing titles.
  5062. FILES will produce a list of all files present
  5063. in the current default drive and sub-directory.
  5064. Try:
  5065.  
  5066.  
  5067. FILES
  5068.  
  5069.  
  5070. you should get a list of all files on disk.
  5071. Now try:
  5072.  
  5073.  
  5074. FILES "DF0:"
  5075.  
  5076.  
  5077. you will get a list of those files on the disk
  5078. in DF0 (assuming there is a disk in there!)
  5079.  
  5080.  
  5081. KILL filespec
  5082. will delete the named file from the disk.
  5083.  
  5084.  
  5085. INPUT "Which file(s) do you want to erase"; A$
  5086. KILL A$
  5087.  
  5088.  
  5089. It is recommended that you write your routines
  5090. such that they first request for confirmation
  5091. before deleting anything in order to check that
  5092. you will not lose anything vital.
  5093.  
  5094.  
  5095. NAME filename1 AS filename2
  5096. allows a specified file to be renamed.
  5097. filename1 receives the name that is specified
  5098. as filename2; note that you can not swap names
  5099. of files or have two files with the same name.
  5100.  
  5101.  
  5102. CHDIR
  5103. changes the default directory. This is helpful
  5104. when using the FILES and NAME commands, and for
  5105. using any newly created or modified files (see
  5106. OPEN, BSAVE etc. later on).
  5107. Your Amiga manuals will explain how the
  5108. directory system works, but briefly: each disk
  5109. drive you have (including a simulated disk
  5110. drive created in the memory by the ramdisk)
  5111. will can be referred to by its device name,
  5112. e.g. DF0:, DF1:, DH0: etc. or by its volume
  5113. name which is it is given when it is formatted.
  5114. It is generally best to refer to files on disk
  5115. by their volume name, that way the system can
  5116. ask you to put the disk in the drive if it
  5117. isn´t already there and it will prompt you to
  5118. put your system disk back in when it needs it.
  5119. On each disk you can store files in one large
  5120. unstructured group, or choose to organise them
  5121. into named directories. A directory is a type
  5122. of filing system folder in which you can store
  5123. those files that are pertinent to a certain
  5124. subject. Each directory can have several sub-
  5125. directories which again can be used to divide
  5126. the information up into useful groups. Files
  5127. with identical filenames can be stored in two
  5128. different directories without causing any
  5129. problems.
  5130. For example you can have on a disk called WORK:
  5131. a directory called ACCOUNTS which can in turn
  5132. have two sub-directories - OFFICE and HOME. A
  5133. file called LETTER in the latter sub-directory
  5134. can be accessed by the pathname:
  5135.  
  5136.  
  5137. "WORK:ACCOUNTS/HOME/LETTER"
  5138.  
  5139.  
  5140. The pathname of the file tells the computer the
  5141. route it will have to take through the various
  5142. directories to access the data.
  5143. Using the CHDIR command you can make the sub-
  5144. directory DF1:ACCOUNTS/HOME the current
  5145. directory. Files held there can then be
  5146. accessed by their short name only and commands
  5147. such as FILES will operate on that specified
  5148. sub-directory if just a filename is used.
  5149.  
  5150.  
  5151. MKDIR pathname
  5152. creates a new sub-directory from within the
  5153. current default drive and directory or via a
  5154. specified pathname.
  5155.  
  5156.  
  5157. RMDIR pathname
  5158. removes an existing named directory as long as
  5159. it contains no files at the time.
  5160.  
  5161.  
  5162. Reading and Writing Disk Files
  5163.  
  5164. All computers need a system for permanently
  5165. storing the information that the user has
  5166. entered, whether this is a program, a list of
  5167. names and addresses, a screen picture or
  5168. whatever.
  5169. Manipulating data files on disk is one of the
  5170. most important jobs your computer can do. Data
  5171. storage is increasingly what computers are
  5172. about, as the development of appropriate
  5173. hardware such as hard disks drop in price so
  5174. computer languages are developing to make it
  5175. easier for the user to access and use data held
  5176. in a permanent record. There are however
  5177. different types of disk file that can be used,
  5178. each appropriate to different circumstances.
  5179. The simplest type of disk data file you can
  5180. create is a completely unstructured record of
  5181. the contents of a specified part of the
  5182. computer´s memory. The most frequently used
  5183. example of this technique is when a graphical
  5184. image on the screen, made up from a pattern of
  5185. dots held in memory, is saved for later recall.
  5186. The way screen pictures are stored and the
  5187. implications of this technique are detailed in
  5188. the section on The Screen.
  5189. The keywords we use for writing and reading
  5190. simple memory-image files are BLOAD and BSAVE.
  5191. To understand how these commands work we must
  5192. learn something about how the computer´s memory
  5193. is structured.
  5194. Every item, or byte, of data (which is large
  5195. enough to store one single letter of a text
  5196. string for example) is stored at a specified
  5197. memory address. The amount of memory available
  5198. varies - on a standard A1200 the number is
  5199. 2*1024*1024 bytes (a kilobyte is 1024 bytes
  5200. rather than a thousand, because of the way that
  5201. computers work internally with binary
  5202. arithmetic, a megabyte is 1024 kbytes).
  5203. Not all of memory will be free to use for data
  5204. - many locations store important working space
  5205. for the operating system and the programs that
  5206. are currently loaded.
  5207. The syntax for BSAVE and BLOAD is:
  5208.  
  5209.  
  5210. BSAVE "filename", start_address, length
  5211. BLOAD "filename", start_address
  5212.  
  5213.  
  5214. The filename can contain a drive identifier and
  5215. sub-directory path.
  5216. The restrictions on the use of filenames is
  5217. rather complex (see your Amiga Manual for an
  5218. exhaustive list) and it is important to ensure
  5219. that your program contains a suitable selection
  5220. of routines to trap nonsense entries by the
  5221. user.
  5222. As an alternative to memory-image files it is
  5223. also possible to define much more highly
  5224. structured files that hold text and numeric
  5225. data in special formats such that the computer
  5226. can at the very least distinguish the length of
  5227. each entry and its position within the file.
  5228. The data within such files consists of
  5229. individual items, normally known as records. It
  5230. is possible to add or extract specific items of
  5231. information from these files or to add data
  5232. items of data to them.
  5233. There are actually two types of structured file
  5234. you can use with MaxonBASIC. The first is known
  5235. as a sequential file and it holds data that the
  5236. computer can only access by stepping through
  5237. item by item in sequence. For example, you can
  5238. read the twentieth record in the file only by
  5239. first reading records 1 to 19. The advantage of
  5240. such a sequential system is that each
  5241. individual item of data can be of any length or
  5242. form that you desire, provided that the end of
  5243. that particular item is signalled somehow,
  5244. whether by a comma, by quote marks ("), by
  5245. carriage returns, or a combination of these.
  5246. The second type is a random access file. This
  5247. uses a system whereby each record of data is of
  5248. a preset and rigid length and form (and we will
  5249. see later that any data that is not of the
  5250. right type has to be converted to match) such
  5251. that the computer can automatically calculate
  5252. the position of item number 20 and jump
  5253. straight there - hence the name random access.
  5254. Because random access files contain items of a
  5255. preset length, old data can safely be
  5256. overwritten by new without any danger of
  5257. obliterating the next entry. Sequential files
  5258. can only have new data added to the end of
  5259. existing files. To remove or insert existing
  5260. items, an old file must be copied item by item
  5261. into a new file, with the appropriate
  5262. modifications made during the process.
  5263. Random access files are therefore often very
  5264. much faster in practice (although this does
  5265. depend on the use to which you are putting
  5266. them). They have the disadvantage that they can
  5267. be more wasteful of disk space - all records
  5268. must be allocated the same room regardless of
  5269. their actual length; this in turn is determined
  5270. by the longest entry you have to accommodate.
  5271. The type and structure of a data file is
  5272. defined when it is created, and this is done by
  5273. the OPEN command. It is no surprise then that
  5274. this can be a rather complicated keyword with
  5275. several parameters:
  5276.  
  5277.  
  5278. OPEN file_spec [FOR mode] AS [#]channel_num
  5279. [LEN=record_size]
  5280.  
  5281.  
  5282. MaxonBASIC can have 255 files open at once, so
  5283. it is fundamental that each of these files is
  5284. designated by a number as it is opened. Any
  5285. future disk reading or writing commands can
  5286. then be told the file they are to work on by
  5287. referring to that number. Assigning the number
  5288. is done by using the AS # part of the OPEN
  5289. command.
  5290. A simple
  5291.  
  5292.  
  5293. OPEN "filename" AS #n
  5294.  
  5295.  
  5296. command will create a new sequential access
  5297. file, or open an existing one of the given name
  5298. for reading and modification.
  5299. However it is possible to define the particular
  5300. type and nature of the file that has been
  5301. opened using the following commands:
  5302.  
  5303. OPEN "name" FOR OUTPUT AS #2
  5304.  
  5305. a sequential file for writing.
  5306.  
  5307. OPEN "name" FOR INPUT AS #9
  5308.  
  5309. a sequential file that is to be read.
  5310.  
  5311. OPEN "name" FOR APPEND AS #1
  5312.  
  5313. a sequential file that already exists and is to
  5314.       have data added to the end.
  5315.  
  5316. OPEN "name" FOR RANDOM AS #5
  5317.  
  5318. a random access file
  5319.  
  5320. The final option is LEN=number.
  5321.  
  5322. This sets the length of each entry in a random
  5323. access file. The default size, if the command
  5324. is omitted, is 128 bytes long. If this command
  5325. is used for sequential files, it controls the
  5326. size of the memory buffer that has to be filled
  5327. before any data actually gets written to disk.
  5328. Disk operations such as writing data are, in
  5329. computer terms, relatively slow. The Amiga very
  5330. sensibly waits until it has a reasonable amount
  5331. of data to write before it goes to the trouble
  5332. of moving the disk drive heads around etc.
  5333.  
  5334.  
  5335. Sequential Files
  5336.  
  5337. Putting data into a sequential file, and
  5338. retrieving the data from such a file, in many
  5339. ways parallels the system used for reading
  5340. information from the keyboard, and writing to
  5341. the screen or printer. Indeed so similar are
  5342. the operations that the keywords used are
  5343. almost identical.
  5344. INPUT# and LINE INPUT# allow data to be read
  5345. from a sequential file. As with input from the
  5346. keyboard, INPUT # reads data that is to be
  5347. assigned to a specified list of variables. LINE
  5348. INPUT# reads an entire line of a sequential
  5349. file until it reaches a carriage return
  5350. character, ignoring any commas or other data
  5351. delimiters and assigning the result to one
  5352. string.
  5353. INPUT$(x) can read x bytes of data from either
  5354. a sequential or a random access file regardless
  5355. of any data separators or field boundaries it
  5356. crosses in doing so.
  5357. As we have seen, putting data into an existing
  5358. sequential file can only be done by adding it
  5359. to the end of those records already saved. The
  5360. keywords to use to do this are WRITE#, PRINT#
  5361. and PRINT# USING.
  5362. As with output to the screen, WRITE#
  5363. automatically separates different data items
  5364. with commas, and encloses strings within
  5365. quotes. The full options available with the
  5366. PRINT# and PRINT# USING commands, and the
  5367. others, are detailed in the Command Reference
  5368. chapter. When used to write data to a file they
  5369. create an exact image of the information that
  5370. would be seen on screen so certain mistakes are
  5371. possible if you are not careful.
  5372. For example:
  5373.  
  5374.  
  5375. PRINT#1, 1,2,3,4,5
  5376.  
  5377.  
  5378. will assume that the commas are to be replaced
  5379. by spaces as on the screen. If the items were
  5380. intended to be stored as separate data items
  5381. the commas have to be PRINTed explicitly as in:
  5382.  
  5383.  
  5384. PRINT #1, 1;",";2;",";3;",";4;",";5;
  5385.  
  5386.  
  5387.  is probably best used for producing formatted
  5388. lines of text that are to be retrieved by the
  5389. LINE INPUT# command, or for storing formatted
  5390. numbers as produced by PRINT# USING.
  5391. Note the distinction between a PRINTed, and
  5392. therefore formatted, line of text, as would be
  5393. produced by a word processor for example, and a
  5394. structured text file such as may be produced
  5395. by, say, a database using the WRITE command. In
  5396. the former case the output will look more
  5397. meaningful to an observer, but the computer
  5398. itself will be unable to determine what each
  5399. individual item of data represents, and where
  5400. one data entry ends and another begins. In the
  5401. latter case every item of data is clearly
  5402. separated from the next by commas and quotes.
  5403. The WIDTH# keyword can be used to limit the
  5404. maximum length of any one line of data that is
  5405. PRINTed to the file.
  5406. Try the following example:
  5407.  
  5408.  
  5409. A$ = "John Smith"
  5410. B$ = "21 New Road"
  5411. C$ = "London"
  5412. OPEN "WRITE.DAT" FOR OUTPUT AS 1
  5413. WRITE #1, A$, B$, C$
  5414. OPEN "PRINT.DAT" FOR OUTPUT AS 2
  5415. PRINT #2, A$, B$, C$
  5416. CLOSE #1, #2
  5417.  
  5418. REM Now read using LINE INPUT
  5419. OPEN "WRITE.DAT" FOR INPUT AS 1
  5420. OPEN "PRINT.DAT" FOR INPUT AS 2
  5421. LINE INPUT #1, A$
  5422. LINE INPUT #2, B$
  5423. PRINT "WRITE data looks like:"
  5424. PRINT A$
  5425. PRINT : PRINT "PRINT data looks like:"
  5426. PRINT B$
  5427. CLOSE
  5428.  
  5429.  
  5430. The file called WRITE.DAT will have the data
  5431. stored internally like this:
  5432.  
  5433.  
  5434. "John Smith","21 New Road","London"
  5435.  
  5436.  
  5437. The file called PRINT.DAT will have data stored
  5438. internally like this:
  5439.  
  5440.  
  5441. John Smith    21 New Road    London
  5442.  
  5443.  
  5444. Any data stored using the PRINT # keyword can
  5445. be formatted within the file in the same way as
  5446. it can on the screen:
  5447.  
  5448.  
  5449. PRINT #2, A$; B$; C$
  5450.  
  5451.  
  5452. would produce a file containing
  5453.  
  5454. John Smith 21 New Road London
  5455. whereas:
  5456.  
  5457.  
  5458. PRINT #2,A$
  5459. PRINT #2,B$
  5460. PRINT #2,C$
  5461.  
  5462.  
  5463. will produce a file like this:
  5464.  
  5465.  
  5466. John Smith
  5467. 21 New Road
  5468. London
  5469.  
  5470.  
  5471. Of course each of these different formats can
  5472. be accessed in different ways with the INPUT#
  5473. and LINE INPUT# commands. For example, using
  5474. the first example file produced with the WRITE#
  5475. command:
  5476.  
  5477.  
  5478.  
  5479.  
  5480. OPEN "WRITE.DAT" FOR INPUT AS 1
  5481. INPUT #1, A$
  5482. PRINT A$
  5483.  
  5484.  
  5485. would produce the result:
  5486.  
  5487.  
  5488.  
  5489.  
  5490. John Smith
  5491.  
  5492.  
  5493. whereas:
  5494.  
  5495.  
  5496.  
  5497.  
  5498. OPEN "WRITE.DAT" FOR INPUT AS 1
  5499. LINE INPUT #1, A$
  5500. PRINT A$
  5501.  
  5502.  
  5503. will produce the result:
  5504.  
  5505.  
  5506.  
  5507.  
  5508. "John Smith","21 New Road","London"
  5509.  
  5510.  
  5511. The LINE INPUT# command has ignored the data
  5512. separators and has read a whole line from the
  5513. file into the variable A$. Conversely in the
  5514. case of the first PRINT example:
  5515.  
  5516.  
  5517. OPEN "PRINT.DAT" FOR INPUT AS 1
  5518. INPUT #1, A$
  5519. PRINT A$
  5520.  
  5521.  
  5522. would produce the result
  5523.  
  5524.  
  5525.  
  5526.  
  5527. John Smith    21 New Road    London
  5528.  
  5529.  
  5530. The INPUT # keyword has found no recognisable
  5531. data separator to denote where one entry
  5532. finishes and the next begins and:
  5533.  
  5534.  
  5535.  
  5536.  
  5537. OPEN "PRINT.DAT" FOR INPUT AS 1
  5538. LINE INPUT #1, A$
  5539. PRINT A$
  5540.  
  5541.  
  5542. would produce the same result.
  5543.  
  5544. Obviously, different techniques are required
  5545. depending on how you choose to store data from
  5546. within your programs.
  5547.  
  5548.  
  5549. Random Access Files
  5550.  
  5551. When using random access files things are
  5552. rather different. The rather inflexible format
  5553. with which these files are stored requires a
  5554. much more complex system of data manipulation
  5555. before the information can be stored on, or
  5556. retrieved from, disk.
  5557. To recap, random access files are divided into
  5558. records, but these are of a fixed length,
  5559. defined at the time the file is opened, and can
  5560. only contain data in a fixed format (actually
  5561. stored as binary data) whether it started off
  5562. as text or numbers of any precision. Many
  5563. different keywords are therefore required to
  5564. convert the data into the specified length and
  5565. the required form.
  5566. Random access files have one or two other
  5567. important traits. Firstly the data held within
  5568. a given record can in, turn, be subdivided into
  5569. a series of fields each of which hold a subset
  5570. of information that is pertinent to the whole
  5571. record. For example, in a club mailing list
  5572. file, each member would merit a record of their
  5573. own, but within that record there will probably
  5574. be a field for NAME, one for ADDRESS, one for
  5575. TELEPHONE NUMBER etc.
  5576. The keyword FIELD is used to allocate space
  5577. within the total record to each sub-division:
  5578.  
  5579. FIELD 1, 20 AS name$, 50 AS address$, 12 AS
  5580. tele$
  5581. Each string variable that is defined in the
  5582. FIELD statement is called, of all things, a
  5583. fielded variable. Fielded variables are rather
  5584. special and should only really be used in
  5585. conjunction with the RSET and LSET commands
  5586. that we have already met, in order to produce a
  5587. precisely-formatted string. Data can not be
  5588. allocated to these variables using other
  5589. commands such as INPUT or they will lose their
  5590. ´fielded´ status.
  5591. A FIELD statement must be issued before reading
  5592. or writing a random access file. Even if the
  5593. records are not subdivided, at least one field
  5594. string must still be defined to hold the data
  5595. that is to be written to the file.
  5596. Because all data held within a random access
  5597. record has to be of the defined length then if
  5598. it is too long it will be truncated and if it
  5599. is too short it has to be padded out to fit. To
  5600. do this all data is converted to a string form
  5601. of the required length, before being saved. To
  5602. recover it again it has to be converted back
  5603. from a string to the data form it originally
  5604. started with.
  5605. The process of writing data to a random access
  5606. file is therefore as follows. Firstly all
  5607. numeric data has to be converted to a string.
  5608. The following keywords do this job:
  5609.  
  5610. MKI$(x)    converts an integer x to a string.
  5611.  
  5612. MKL$(x)    converts a long integer x to a
  5613. string.
  5614.  
  5615. MKS$(x)    converts a single precision number x
  5616. to a string.
  5617.  
  5618. MKD$(x)    converts a double precision number x
  5619. to a string.
  5620.  
  5621. The next step is that the resulting string has
  5622. to be placed in the random access buffer, an
  5623. area of memory automatically reserved as
  5624. workspace when the file is opened, ready for
  5625. writing to the disk. As this is done the data
  5626. is padded to the length required to fit either
  5627. the whole record or a field to which it is to
  5628. be assigned. This is done through the use of
  5629. the keywords LSET or RSET. LSET fits the given
  5630. string to the left hand end of a padded string
  5631. of the required length. RSET fits it to the
  5632. right hand end of a padded string of the
  5633. required length.
  5634.  
  5635. For example the command:
  5636.  
  5637.  
  5638. RSET A$=MKL$(x)
  5639.  
  5640.  
  5641. will fit the string equivalent of the long
  5642. integer variable x, into the right hand edge of
  5643. the fielded variable (A$) ready for storage.
  5644. If the name of the variable, A$, has been
  5645. designated as a field occupying a subsection of
  5646. the total record length (see above) the
  5647. computer will automatically store the data in
  5648. the correct place within the total buffer. In
  5649. this case RSET or LSET will place the data into
  5650. the right or left hand end of the room
  5651. allocated to that variable.
  5652. Remember that MKtype$ is only necessary when
  5653. storing numeric data. Commands such as:
  5654.  
  5655.  
  5656. RSET A$=B$
  5657.  
  5658.  
  5659. or:
  5660.  
  5661.  
  5662. RSET A$="Fred Smith"
  5663.  
  5664.  
  5665. can be used to place text data directly into a
  5666. fielded variable.
  5667. When all of the fielded variables have been
  5668. assigned the appropriate data, or left blank if
  5669. required, the buffer memory can be copied onto
  5670. the actual disk.
  5671. The command required is n, x, which writes the
  5672. current value of the buffer data to the correct
  5673. place within file number n, as record number x.
  5674. If x is omitted the next record in the file is
  5675. written. The buffer is ´emptied´ as a result of
  5676. this command so that the next record to be
  5677. written will be starting with a clean sheet, as
  5678. it were.
  5679. That was many new concepts to take in, but the
  5680. process is really very simple if you take it
  5681. step by step. Here is a simple example:
  5682.  
  5683.  
  5684. A$="John Smith"
  5685. B$="21 New Road London"
  5686. X%=21
  5687. OPEN "PERSONAL.DAT" FOR RANDOM AS #1 LEN=65
  5688. FIELD 1, 20 AS name$, 40 AS address$, 5 AS age$
  5689. LSET name$=A$
  5690. LSET address$=B$
  5691. LSET age$=MKI$(X%)
  5692. PUT 1,1
  5693.  
  5694.  
  5695. Retrieving data from a random access file is a
  5696. slightly simpler process. The opposite of the
  5697. PUT command is GET. Before issuing this
  5698. command, the field variables should again have
  5699. been declared in the program. Once one record
  5700. has been read these fielded variables can then
  5701. be used immediately, for example to print
  5702. individual sections of the data, or the
  5703. retrieved data can be assigned to other
  5704. variables for manipulation freeing the fielded
  5705. variables for reading another record.
  5706. If the data that has been retrieved was
  5707. originally assigned to a numeric variable it
  5708. can be converted back to its original form
  5709. using one of the following commands.
  5710.  
  5711. CVI(string$)  converts the data back to an
  5712. integer.
  5713.  
  5714. CVL(string$)  converts data back to a long
  5715. integer.
  5716.  
  5717. CVS(string$)  converts data back to a single
  5718. precision number.
  5719.  
  5720. CVD(string$)  converts data back to a double
  5721. precision number.
  5722.  
  5723. Note that these commands work in a very
  5724. different way to the VAL keyword, and they
  5725. cannot be used in its place. Note also that
  5726. random access files require that you can
  5727. anticipate the likely precision of numbers
  5728. before they are converted. Sequential files are
  5729. more tolerant in this respect - a numeric
  5730. variable of an unspecified type can be used to
  5731. hold a given value and that variable will to an
  5732. extent adjust its internal format to match the
  5733. data it is assigned.
  5734.  
  5735.  
  5736. OPEN "PERSONAL.DAT" FOR RANDOM AS #1 LEN=65
  5737. FIELD 1, 20 AS name$, 40 AS address$, 5 AS age$
  5738. GET 1,1
  5739. PRINT name$; CVI(age$)
  5740.  
  5741.  
  5742. will produce the output
  5743.  
  5744.  
  5745. John Smith     21
  5746.  
  5747.  
  5748. Note that the variable name$ is padded with
  5749. spaces to the length defined in the field
  5750. statement; you can use RTRIM$ to cut this data
  5751. down to size.
  5752. Finally we have the keywords LOF, LOC and EOF
  5753. which are three functions that allow the
  5754. program to keep track of the size of a file and
  5755. the current position of the pointer within it.
  5756. LOF stands for Length Of File (in bytes).
  5757. LOC stands for the LOCation of the data
  5758. pointer. When using random access files it
  5759. reports which number entry was read by the last
  5760. GET command or was last written to by PUT. For
  5761. sequential files LOC is often less useful. It
  5762. returns the current byte position of the file
  5763. pointer divided by 128. If your records are of
  5764. a set length the actual record pointed to can
  5765. be calculated from this value even if your data
  5766. entries are longer or shorter than 128 bytes.
  5767.  
  5768. EOF, standing for End Of File, is an invaluable
  5769. logical function that reports TRUE (-1) when
  5770. the data pointer has reached the last data
  5771. entry. It is usually used in logical loops to
  5772. trigger the end of a certain operation as in
  5773. this example which reads an ASCII file and
  5774. copies it to the printer:
  5775.  
  5776.  
  5777. SUB Print_File
  5778.  FILES
  5779.  INPUT "Which file do you want to print?"; A$
  5780.  OPEN A$ FOR INPUT AS #1
  5781.  WHILE NOT EOF(1)
  5782.      LINE INPUT #1,aline$
  5783.      LPRINT aline$
  5784.  WEND
  5785.  CLOSE #1
  5786. END SUB
  5787.  
  5788.  
  5789. Shutting down a file is a very simple affair -
  5790. just use the command CLOSE for either
  5791. sequential or random access data files. A list
  5792. of numbers can be given to close several files
  5793. at once, and the keyword CLOSE without any
  5794. specified numbers shuts down all files.
  5795. The keyword RESET has the same effect. All
  5796. FIELD statements are forgotten at the same
  5797. time. The various program termination commands
  5798. STOP, END and SYSTEM also automatically shut
  5799. down all files.
  5800. All OPENed files must be closed if the disk is
  5801. to be removed while the program is running or
  5802. data may be ruined. At the very least any data
  5803. still held in memory buffers will be lost.
  5804. Because of the threat of power cuts you can
  5805. consider including a routine in all your
  5806. programs that, perhaps at a timed interval,
  5807. makes a backup copy of the current files.
  5808. The final command that may be of value is the
  5809. keyword VARPTR#. This will return the address
  5810. of the buffer used to store information that
  5811. has just been read from, or just prepared for
  5812. sending to, the file number. This keyword is
  5813. principally designed to pass information to
  5814. routines written in other languages such as
  5815. assembler to allow them to access the data held
  5816. by your MaxonBASIC program.
  5817.  
  5818.  
  5819. Error Handling
  5820.  
  5821. Error Handling is a means whereby the
  5822. programmer can anticipate, and make allowance
  5823. for, undesirable circumstances whilst the
  5824. program is running. These ´errors´ are of three
  5825. main types. They may result from a problem in
  5826. the hardware such as no paper in the printer,
  5827. no room left on the disk or no disk in the disk
  5828. drive. They may follow an incorrect data entry
  5829. or response by the user. Finally they may be
  5830. triggered by some error in the programming that
  5831. did not become apparent under test.
  5832. MaxonBASIC, in conjunction with the Amiga
  5833. operating system can pick up, and determine the
  5834. nature of, a wide selection of errors and it is
  5835. good practice that your program should try to
  5836. prepare for as many of these as possible. Error
  5837. trapping routines can be tedious to plan and
  5838. write, and can seem to take a disproportionate
  5839. amount of time compared to the real nuts and
  5840. bolts of your program, but if done well they
  5841. are the hallmark of a professional quality
  5842. program.
  5843. We have already seen how it is possible to
  5844. enter simple error traps by specifying certain
  5845. logical conditions that accept or reject data
  5846. entered by the user. For example:
  5847.  
  5848.  
  5849. DO
  5850.  LOCATE 1,2
  5851.  INPUT "Size of curve (1-4) ",s%
  5852.  y%=length/s%
  5853. LOOP WHILE s%>=1 AND s%<=4
  5854.  
  5855.  
  5856. This continues to ask the question until the
  5857. user puts on his spectacles and provides an
  5858. acceptable answer. Note also that the variable
  5859. s% is an integer type so that an entry such as
  5860. 1.4 would be converted to a usable number.
  5861. However, it is part of the nature of error
  5862. catching routines that there are always more
  5863. possible ways that the user can catch you out
  5864. than you will ever anticipate in the first
  5865. attempt; let´s say he enters the value 0 -
  5866. you´ve forgotten to trap this and you will get
  5867. a runtime error on the fourth line because of
  5868. division by zero.
  5869. It is also inevitable that ´errors´ can occur
  5870. that you will be unable to prevent happening,
  5871. such as an unformatted disc being placed in the
  5872. disc drive and so on. We therefore need a
  5873. system of dealing with such errors no matter
  5874. when and how they occur.
  5875. Errors that are produced through a problem in
  5876. the hardware or through a mistake in the
  5877. program, such as trying to divide an expression
  5878. by a variable which has somehow been assigned a
  5879. value of zero, will generate an error number
  5880. specific to that particular situation.
  5881. To allow the maximum use of this facility there
  5882. are a range of functions that will report the
  5883. nature of the error, together with the line
  5884. number which was being executed when the
  5885. problem occurred. ERR is the function that
  5886. returns the error code and ERL returns the line
  5887. number where it happened. From these your
  5888. routines can deduce what the problem was and
  5889. decide how to fix it (e.g. print a message such
  5890. as There is no disk in the drive and then
  5891. restart the data input routine).
  5892. The nature of errors means that they can only
  5893. be anticipated to occur at un-anticipated
  5894. times. Similarly the response to the error has
  5895. to be ready to come into operation at any time.
  5896. Hence error handling really has to be organised
  5897. as a background event trap.
  5898.  
  5899. The command sequence we use is therefore is ON
  5900. ERROR GOTO which causes a jump to a specific
  5901. line number or line label as soon as any error
  5902. occurs. The line that is jumped to will usually
  5903. be the beginning of a routine that decides
  5904. exactly which error has occurred, deals with it
  5905. in some way, and decides where (if at all) that
  5906. the program is to resume execution.
  5907. The keyword RESUME specifies which line number
  5908. or line label the program is to return to
  5909. following the specific error correction routine
  5910. has been completed.
  5911. Here is an example:
  5912.  
  5913.  
  5914. a$="TEST.DAT"
  5915.  
  5916. Kill_File:
  5917.  
  5918. ON ERROR GOTO Kill_Problem
  5919. KILL a$
  5920.  
  5921. ON ERROR GOTO 0    ´ Normal error reports
  5922.  
  5923. STOP
  5924.  
  5925. Kill_Problem:
  5926.  
  5927. ErrNum=ERR
  5928. REM Can´t use ERR directly in CASE
  5929.  
  5930.  
  5931. SELECT CASE ErrNum
  5932. ´Error 53 is File not Found
  5933.  CASE 53
  5934.      FILES
  5935.      PRINT a$;" not found"
  5936.      INPUT "Please give a valid file";a$
  5937. CASE ELSE  PRINT "Fatal error ";ERR : STOP
  5938. END SELECT
  5939. RESUME Kill_File
  5940.  
  5941.  
  5942. As an extension of the error facility the
  5943. programmer can also add to the list of errors
  5944. that will be reported by specifying new
  5945. conditions that are to be regarded as problems
  5946. of some kind. The keyword ERROR can be used in
  5947. this context to define the error that is
  5948. required. It can be used to extend the range of
  5949. conditions under which an existing error number
  5950. is triggered:
  5951. For example: runtime error 5 is Illegal
  5952. Function Call - you might want to use that in
  5953. one of your own user-defined functions as shown
  5954. on the next page:
  5955.  
  5956.  
  5957. REM Factorials by iteration
  5958.  
  5959. FUNCTION Factorial#(x)
  5960. STATIC Temp#,i
  5961.  
  5962. REM Can´t do 0! or 1!
  5963.  IF x<2 THEN ERROR 5
  5964.  
  5965.  Temp#=1
  5966.  FOR i=2 to x
  5967.      Temp#=Temp#*i
  5968.  NEXT i
  5969.  Factorial#=Temp#
  5970. END FUNCTION
  5971.  
  5972.  
  5973. The ERROR keyword can also be used to define
  5974. the conditions that would trigger an error
  5975. number that has not previously been used. This
  5976. is invaluable when using unusual peripherals
  5977. for which there are no pre-defined errors, and
  5978. can even be used to catch situations such as
  5979. when a data input has exceeded a permissible
  5980. maximum, or is not of the appropriate format
  5981. etc.
  5982.  
  5983.  
  5984. Get_Input:
  5985.  
  5986. ON ERROR GOTO Validate
  5987. INPUT "Choice (1-4)";Choice
  5988. IF Choice<1 OR Choice >4 THEN ERROR 200
  5989. INPUT "Name, please"; Name$
  5990. IF LEN(Name$) > 19 THEN ERROR 201
  5991.  
  5992. REM Normal error reporting
  5993. ON ERROR GOTO 0
  5994.  
  5995. Validate:
  5996. ErrNum=ERR
  5997. SELECT CASE ErrNum
  5998.  CASE 200
  5999.      PRINT"Please select a number between 1 and
  6000. 4"
  6001.  CASE 201
  6002.      PRINT "Names must be less than 20
  6003. characters"
  6004.  CASE ELSE PRINT "Unknown validation error" :
  6005. STOP
  6006. END SELECT
  6007. RESUME Get_Input
  6008.  
  6009.  
  6010. This routine most usefully works in conjunction
  6011. with an ON ERROR statement as the newly defined
  6012. number can then, if triggered, cause a jump to
  6013. a sub-program which will print an explanatory
  6014. comment. If error handling is not enabled the
  6015. effect of the newly defined error, when
  6016. triggered, is to print the message Runtime
  6017. error nn where nn is the error number.
  6018.  
  6019.  
  6020. End Sub
  6021.  
  6022. That was a tour of the concepts that underlie
  6023. MaxonBASIC. Hopefully it has provided you with
  6024. a good enough grounding to begin to experiment
  6025. with the various commands in detail.
  6026. There are several ways to expand your BASIC
  6027. programming skills.
  6028. Firstly practice. You will get a feel for how
  6029. the different commands work by trying them out
  6030. in routines of your own devising.
  6031. Secondly type in routines from magazines and
  6032. books (you will be pleasantly surprised by how
  6033. many listings work in MaxonBASIC with only the
  6034. minimum of modification so you do not even have
  6035. to restrict yourself to Amiga programs). There
  6036. is never one correct way of programming a given
  6037. task, any dozen people would probably come up
  6038. with a dozen different solutions to a given
  6039. problem. Entering listings is therefore an
  6040. invaluable way of learning new ways of looking
  6041. at things.
  6042. Remember, you do not have to re-invent the
  6043. wheel every time you sit down at the keyboard.
  6044. Many routines have already been created that
  6045. can be used within your own programs, probably
  6046. with greater speed or using less memory space
  6047. than you would have been able to come up with
  6048. on your own.
  6049. The bibliography lists a selection of books
  6050. that may be useful in teaching programming
  6051. techniques.
  6052.  
  6053.