home *** CD-ROM | disk | FTP | other *** search
/ Global Amiga Experience / globalamigaexperience.iso / compressed / development / heliosdemodisk3.dms / heliosdemodisk3.adf / Tutorials / HeliOSLanguageTutorial2.doc < prev    next >
Text File  |  1994-12-18  |  72KB  |  1,813 lines

  1.  
  2. ------------------------------------------------
  3. An Introduction to Elementary HeliOS Programming
  4. ------------------------------------------------
  5.  
  6. This introductory tutorial is intended to explain a few general ideas
  7. which may help you get started with HeliOS.
  8.  
  9. Because simple once-only statements of fact are not the best way of
  10. introducing a complex subject, we have provided tutorials which cover
  11. similar ground in different ways.
  12.  
  13. Some of the ideas in this tutorial will be different expressions of
  14. ideas related in other tutorials, and some of the material will be new.
  15.  
  16. Hopefully this many-faceted approach will help make some of the more
  17. unfamiliar concepts accessible to most people, and once you are confident
  18. enough to write your own first programs you will be able to pick up
  19. further knowledge directly from the reference material as you need it.
  20.  
  21. So don't just say "Oh..we've already read this!" and gloss over things,
  22. unless you already are very confident of your understanding, because
  23. there may be some new ideas in here.....
  24.  
  25. ---------------------------
  26. Getting started with HeliOS
  27. ---------------------------
  28.  
  29. HeliOS is a Forth-like language, especially in its simpler aspects, and
  30. the more sophisticated features of HeliOS build upon a central core of
  31. functions which are closely related to fig-Forth.
  32.  
  33. This tutorial will discuss a few simple concepts which relate to Forth
  34. and Amiga programming in general without delving into deeper aspects
  35. of HeliOS.  This is not a detailed HeliOS language lesson, and does not
  36. deal in depth with programming the Amiga operating system and hardware.
  37.  
  38. It will not take long before you are able to write your own first HeliOS
  39. program.  If you follow the introductory instructions and get the small
  40. demonstration programs working you will soon be all ready to start writing
  41. real working programs which include text and graphics.
  42.  
  43. To help you get started with your own programs we include a standard
  44. "start up and close down" mini-program which you can use as a general
  45. basis for all your early experimental code.  This "framework" program
  46. will enable you to open screens and windows, get user input, print text
  47. and display graphics: all the elements of simple programming in fact.
  48.  
  49. We also include several source code files which introduce slightly more
  50. advanced techniques while still being quite accessible to beginners.  It
  51. is easy to modify these programs to make your own simple games and from
  52. there you can progress to studying the more complex examples provided,
  53. such as the full source code for the HeliOS "Defender" game.
  54.  
  55. It may be a little boring, but even if you are not new to Forth-type
  56. lanuages please read through the introductory tutorials BEFORE trying
  57. to actually change any of the example programs provided.  This will help
  58. prevent initial frustration, because HeliOS is a very unusual language
  59. and a certain amount of insight into how HeliOS works is necessary even
  60. for experienced programmers.
  61.  
  62. ------------------------------------------------------
  63. What do the terms "Compiling" and "Interpreting" mean?
  64. ------------------------------------------------------
  65.  
  66. The text which contains the program instructions you wish to give to the
  67. computer is called "source" code, because it is the "starting" point for
  68. a translation process.  This translation produces the actual "executable"
  69. code which is executed by the computer's CPU (central processing unit).
  70.  
  71. The process of producing machine-readable CPU executable code from the
  72. human-readable source code is known as "compiling".  Strictly speaking,
  73. "compiling" is the term used to desribe the process whereby the source
  74. code for a program is converted to executable code in the form of a file
  75. which can be "run" or "executed" later.
  76.  
  77. Some computer languages, rather than compiling source code into executable
  78. code as a whole, translate and execute each bit of source code as they go.
  79. This process is called "interpreting".  The latter languages run programs
  80. very slowly because of the inefficient on-the-fly interpretation process.
  81. They do, however, have the advantage that you can "try out" code at once
  82. to see how it works: an "interpretive" language gives an instant response.
  83.  
  84. The pure "compiler" languages produce much faster final code, but in turn
  85. they suffer from a rather serious disadvantage in that the process of
  86. compilation is quite involved and time consuming.  This means that the
  87. programmer's task of compiling, testing, rewriting, and recompiling can
  88. be a very slow and non-interactive (often frustrating) occupation.
  89.  
  90. HeliOS is a "compiler", but it also has an "interpretive mode" as well,
  91. which is a good thing because it means that you can create fast compiled
  92. programs AND test them interactively as you go.  This feature of HeliOS
  93. alone is a very good reason for using it as a "learning" language, and
  94. the efficiency with which it both "interprets" and "compiles" lifts it
  95. above any other language on the Amiga in this respect.
  96.  
  97.  
  98. ------------------------
  99. HeliOS Program Structure
  100. ------------------------
  101.  
  102. The first thing to learn is the correct way to write your "source code",
  103. because any computer language can only understand code in a very specific
  104. text format.  Fortunately there are very few "rules" to learn with HeliOS
  105. and there are no constraints such as "line numbers", or "strictly typed
  106. variables".
  107.  
  108. Traditional Forth did employ a quite rigid and unusual form of source code
  109. stored in special "blocks", but HeliOS allows great freedom of text layout
  110. within the framework of a few simple but necessary rules.
  111.  
  112. Some computer languages simply allow a whole program to be one single long
  113. "stream" of code, but this can be highly confusing.  The more sophisticated
  114. languages allow code to be broken down into easy-to-handle sub-sections, or
  115. "subroutines", which can in turn be logically organised in a clear and
  116. functionally efficient manner.  The latter type of language is called a
  117. "structured language".
  118.  
  119. HeliOS programs are highly structured, and the language uses a collection
  120. of subroutines, often called "Words", which are created using a source code
  121. construct called the "colon definition". This name is used because each
  122. new subroutine definition starts with the colon ":" character.
  123.  
  124. Within the "colon definitions" which define your functional code, there may
  125. be used all the usual logical constructs such as "IF-ELSE-THEN", "DO-LOOP",
  126. "BEGIN-UNTIL" etc etc.  All these constructs are easy to use and allow you
  127. to create neat and easy to read logically structured code.
  128.  
  129. In effect HeliOS programming consists in defining new words which extend the
  130. language itself, and as such is a very flexible and intuitive process.  You
  131. can lay out programs in a very free way, and you may use any text editor
  132. which produces standard ASCII files, although it well generally be most
  133. convenient to use the integrated HeliOS editors because you can compile
  134. code directly from there.
  135.  
  136. -------------------
  137. "Colon Definitions"
  138. -------------------
  139.  
  140. The colon definition allows you to define an action and give a name to the
  141. resulting functional unit.  The new "subroutine", or "Word", can then
  142. be used by simply entering its name in later source code. You have actually
  143. created a new operator which is just as much a part of the language as the
  144. initial HeliOS Core vocabulary functions.
  145.  
  146. The start of a new subroutine is designated by a colon, and, after the code
  147. specifying what the new word does, we end the definition with a semicolon.
  148.  
  149. Look at the example below:
  150.  
  151.   : NEWWORD   |<--------definition-------->| ;
  152.  
  153. Here you can see the colon and the semicolon with the definition placed in
  154. between.  Note that immediately following the colon is the word NEWWORD,
  155. and, as you may have guessed, this is the name of our new subroutine.
  156.  
  157. Remember that YOU choose the name of the new function: it can be anything
  158. you like, but always try to use distinctive and descriptive terms to make
  159. your code more comprehensible to you.  If you choose names carefully your
  160. code can be made almost as readable as English language. On the other hand
  161. it is very easy to write very incomprehensible code indeed......
  162.  
  163. A lot of your HeliOS code will consist of the use of the colon definition,
  164. so you will soon become familiar with it.  We will give plenty of examples
  165. later in the tutorial.
  166.  
  167.  
  168. ---------------------------------
  169. HeliOS "WORDS" and the dictionary
  170. ---------------------------------
  171.  
  172. HeliOS subroutines are called "WORDS", the total set of words available is
  173. called the "VOCABULARY", and the place where all the words are stored in
  174. the computer's memory is called the "DICTIONARY".
  175.  
  176. Because HeliOS source code is concerned with very "linguistically" oriented
  177. activities, and because the definition and use of language is a very vital
  178. part of HeliOS, the term "WORD" tends to become a rather overworked part of
  179. HelIOS terminology.  This all stems from traditional Forth usage.
  180.  
  181. Historically Forth programmers have always referred to subroutines and
  182. their definitions as 'WORDS', but this can be confusing because the term
  183. WORD was used in several different ways in Forth computing parlance -
  184.  
  185.   1. It defines a quantity of memory - 2 bytes or 16 bits. ( see later )
  186.  
  187.   2. It is used to refer to the basic functional units of the Forth
  188.      Language in terms of WHAT THEY DO operationally.
  189.  
  190.   3. It is used in the English Language sense to refer to the actual NAME
  191.      of the subroutine - the actual letters which you type to define it.
  192.  
  193. A little care has to be taken, when you are first starting with HeliOS, to
  194. understand the context in which the word "WORD" is used!
  195.  
  196. All the commands and subroutines that HeliOS uses, including both your own
  197. subroutines and predefined HeliOS word definitions are stored in the HeliOS
  198. 'dictionary'.
  199.  
  200. As each new definition is added, the free space in the HeliOS dictionary is
  201. reduced. This space has a fixed limit, and you can always see how much room
  202. is left in the dictionary by looking at the status display at the top of
  203. the HeliOS screen.  When the dictionary is full you can write no more code,
  204. but since HeliOS compiled code is VERY compact this would mean that you had
  205. already written a very large program indeed.
  206.  
  207. You can list the contents of the Dictionary simply by typing "VLIST" at the
  208. command line (described later), or using the menu options in the Interpreter
  209. "HeliOS" menu.
  210.  
  211. It is important to understand how the dictionary works because the general
  212. compilation method used by HeliOS is quite unlike that of most other Amiga
  213. languages.
  214.  
  215.  
  216. Basically this is what happens -
  217.  
  218.   1. You create a subroutine by typing in one or more lines of source code.
  219.  
  220.   2. The executable code is then "compiled" and stored in the dictionary
  221.      in a form which can be "understood" by the computer.
  222.  
  223.   3. The name you gave the new "word" is stored SEPARATELY in a special list
  224.      rather like an index, which allows the word to be found and used later
  225.      merely by entering its name.
  226.  
  227.  
  228.   ( SPECIAL NOTE about 3. above:
  229.  
  230.      HeliOS is very different from traditional Forth in the way that it
  231.      stores word names in a separate list.  If you are a seasoned Forth
  232.      programmer, or have a book on traditional Forth, you should read and
  233.      remember the following note, as it will beneficially effect your whole
  234.      programming style.
  235.  
  236.      When a HeliOS program is finally run the list of word names is no
  237.      longer needed.  This means that when you produce completed stand-
  238.      alone programs the list of names can be omitted.  If you think about
  239.      it you will see that this is very useful, because it means that you
  240.      can use long descriptive names for your subroutines without having
  241.      to worry about them cluttering up your program later.
  242.  
  243.      This may seem very obvious, but traditional Forth actually stored the
  244.      word names permanently within the program code and you may find books
  245.      which advise you to use short names for this reason.  Using HeliOS
  246.      you can relax and use word names as long as you like - just try to
  247.      make your names useful and descriptive. )
  248.  
  249.  
  250. Every time these three steps are performed the compiled code is added to
  251. the dictionary.  If you recompile a subroutine and do not change its name,
  252. the earlier version(s), although still stored in the dictionary, will be
  253. left in place but superceded by the latest addition.  This means that your
  254. latest definition will always be the one used in response to typing the
  255. subroutine name, but the "old" definitions will still be there hidden in
  256. the dictionary.
  257.  
  258. During a typical session you may well work on a program by continually
  259. recompiling and testing code.  If you make no attempt to clear previous
  260. additions to the dictionary then it will be filled quite quickly.
  261.  
  262. The dictionary can be totally cleared back to the fixed CORE dictionary
  263. ( the set of standard words which are available at startup ) by using the
  264. expression:
  265.  
  266.     FORGET **CORE**
  267.  
  268. Placing this at the start of a program source code file ensures that you
  269. can keep recompiling the source code without subroutine definitions being
  270. duplicated and without the dictionary gradually being filled up.
  271.  
  272. We will from now on call the basic set of HeliOS commands, which is ALWAYS
  273. available, the CORE dictionary (or vocabulary), and all the subroutines
  274. defined in your own code as the USER dictionary (or vocabulary).
  275.  
  276. Here are three command words to list the vocabularies:
  277.  
  278. CVLIST -> List the CORE vocabulary
  279. UVLIST -> List the USER vocabulary
  280. VLIST  -> List the CORE vocabulary followed by the USER vocabulary
  281.  
  282. ------------------------------------
  283. Computer Memory and the HeliOS Stack
  284. ------------------------------------
  285.  
  286. Memory is the basic storage medium for program code and data.
  287.  
  288. Memory can be thought of as a series of cells, each of which can hold a
  289. numerical value, and the way in which each value is interpreted is largely
  290. determined by the code within your program.
  291.  
  292. HeliOS uses a special device called a STACK, which is actually just a small
  293. organised subsection of the large general memory pool.  Rather than being
  294. randomly accessed in any order, the stack is accessed sequentially like a
  295. pile of plates, or a deck of cards.
  296.  
  297. Data is, in general, placed on the top of the stack and then removed when
  298. it is needed later.
  299.  
  300. As more and more items are stored on the stack it grows in size, and the
  301. oldest items, those placed on the stack first, are left at the bottom.
  302.  
  303. The HeliOS stack is employed to store sets of numbers which are going to be
  304. used almost at once by other subroutines, and can be regarded as a quick
  305. temporary store.  It can also be looked upon as a "channel" of information
  306. between sequential operations.  Typically one operation will put a number
  307. onto the stack, and the next will take the number off the stack and use it.
  308. You can think of it almost as a type of "messenger" carrying data between
  309. different parts of your program: a kind of "dumb waiter".
  310.  
  311. Many HeliOS words, including your own program subroutines, look for and
  312. return values on the stack, and this process is called "parameter passing".
  313.  
  314. In the past many would-be Forth programmers were initially terrified of
  315. using the stack because they had never used such a thing and had perhaps
  316. used other languages which employed NAMED VARIABLES rather than a stack.
  317. Actually you will soon see that the stack is ridiculously easy to use and
  318. gives you a lot more programming power than the restrictive use of variables
  319. for all parameter passing.  In HeliOS you can use the stack or you can use
  320. named variables, or both together: so you have more power and more choice.
  321.  
  322. HeliOS provides a large number of words for manipulating the stack,
  323. and these should be learned as soon as possible - they will soon become
  324. familiar since they are in constant use in ALL your HeliOS code.  This is
  325. because you are constantly needing to adjust the position of data items
  326. on the stack, as well as adding, deleting, and duplicating items.
  327.  
  328. Traditional Forth had just a few stack control words, and managed any more
  329. complex operations needed by combining many of these simple words together.
  330. Because the names used in Forth for stack operators are short and cryptic,
  331. complicated combinations of them are very unreadable.  Not only this, but
  332. use of a lot of generalised words to do a job rather than one specific word
  333. is very inefficient.  This was THE major problem with early Forth systems.
  334.  
  335. This problem of "stack control" is one of the weakest parts of traditional
  336. Forth, and is largely responsible for Forth code getting a reputation for
  337. being very unreadable.  This is a shame, because Forth was potentially the
  338. most "readable" of all computer languages, and it was only the limited
  339. vocabulary of early Forth systems which caused the difficulty.
  340.  
  341. HeliOS has removed the necessity for worry over stack manipulation
  342. by providing the most complete set of specialised words ever available
  343. in a Forth-type language.  Try to gradually incorporate more and more of
  344. these words into your knowledge of HeliOS, so that you can use just the
  345. right specific word for the job rather than a series of less appropriate
  346. ones.
  347.  
  348. HeliOS has adopted another totally new philosophy which departs from Forth
  349. tradition: all the stack control words in HeliOS are machine coded for
  350. maximum speed and efficiency.
  351.  
  352. We have dwelt perhaps overmuch on the stack, because the use of the stack
  353. will be really important throughout all of your HeliOS programming.  The
  354. concept of always using the minimum of stack control words throughout
  355. your code is VERY important if your programs are to be readable, easily
  356. maintained, and fast in operation.
  357.  
  358. Before leaving this important subject, here is a very quick practical
  359. example of stack manipulation so that you can see what it is all about.
  360.  
  361. Take a stack with four numbers on it:      1,  2,  3,  4
  362.  
  363. Imagine that the "4" is at the top, and the "1" is at the bottom.
  364.  
  365. Suppose that we want to duplicate the third number from the top and
  366. place a copy of it on the top of the stack. ( Believe it or not, this
  367. sort of thing is quite commonly required! )
  368.  
  369. So we need to operate on our initial stack to get:  1,  2,  3,  4,  2
  370.  
  371. Let us assume that we have four stack operators:
  372.  
  373.    DUP           - this duplicates the number on top of the stack
  374.                    eg.  1, 2, 3, 4   ->   1, 2, 3, 4, 4
  375.  
  376.    SWAP          - this exchanges the top two stack items
  377.                    eg.  1, 2, 3, 4   ->   1, 2, 4, 3
  378.  
  379.    DSWAP         - this exchanges the top two "double" stack items
  380.                    eg.  1, 2, 3, 4   ->   3, 4, 1, 2
  381.  
  382.    ROT           - this REMOVES the third number on the stack and
  383.                    puts it onto the top
  384.                    eg.  1, 2, 3, 4   ->   1, 3, 4, 2
  385.  
  386. How do we solve our simple problem?
  387.  
  388. Why not try it as an exercise on paper?
  389.  
  390. We could do the following:                      1, 2, 3, 4
  391.  
  392.                                    ROT   ->
  393.                                                 1, 3, 4, 2
  394.  
  395.                                    DUP   ->
  396.                                                 1, 3, 4, 2, 2
  397.  
  398.                                    ROT   ->
  399.                                                 1, 3, 2, 2, 4
  400.  
  401.                                    DSWAP ->
  402.                                                 1, 2, 4, 3, 2
  403.  
  404.                                    ROT   ->
  405.                                                 1, 2, 3, 2, 4
  406.  
  407.                                    SWAP  ->
  408.                                                 1, 2, 3, 4, 2
  409.  
  410. Success!  We did it! This way is slow, but it DOES work.
  411.  
  412. ( Actually it can be done quicker than this - did you manage it? )
  413.  
  414.  
  415. But look......we have the following series of operators:
  416.  
  417.   "ROT DUP ROT DSWAP ROT SWAP"
  418.  
  419. This is horrible to read, and even worse to debug when combined with a lot
  420. of other similar sequences.  It is also very time consuming to compile and
  421. execute, since it takes SIX words to do one simple job.  If we could do
  422. this operation in ONE word we should have SIX times better code - it is
  423. as simple as that.
  424.  
  425. HeliOS would do the following in one word - and it would be a very fast
  426. internally machine coded word too.
  427.  
  428. HeliOS would say:                         1, 2, 3, 4
  429.  
  430.                              3PICK ->
  431.  
  432.                                           1, 2, 3, 4, 2
  433.  
  434.  
  435. So we have used the special operator "3PICK" = "pick out the third item"
  436.  
  437. We have written a program which compiles AND runs SIX times faster than
  438. the first method.
  439.  
  440. This kind of thing is fundamental to good HeliOS programming, and you will
  441. constantly come up against coding tasks exactly like the above example.
  442.  
  443.  
  444. ------------------------
  445. The HeliOS stack display
  446. ------------------------
  447.  
  448. To help you get accustomed to the working of the stack, HeliOS has a
  449. permanent stack display at the top of the Interpreter window.
  450.  
  451. Try doing a few calculations and manipulations like the examples above
  452. and watch the stack display.  This will soon give you a feeling for how
  453. the HeliOS stack works, because seeing the numbers change in the set of
  454. cells displayed graphically on screen is an excellent aid in visualising
  455. stack operations.
  456.  
  457.  
  458. ----------------------------------------------------------------
  459. Passing Parameters between HeliOS Words and using Stack Diagrams
  460. ----------------------------------------------------------------
  461.  
  462. Let us take, as a simple example, the HeliOS Word "FPENSET". This
  463. word sets the foreground text pen colour, which is simply a number.  On
  464. a four colour screen the text could be displayed in colour 0, 1, 2 or 3.
  465.  
  466. Let us assume we are starting from an empty stack.
  467.  
  468. Our word FPENSET needs to know what colour we want it to use, and this is
  469. done very simply in HeliOS by passing the colour number as follows:
  470.  
  471.                       1 FPENSET            for  "colour 1"
  472.  
  473.           or          3 FPENSET            for  "colour 3"
  474.  
  475.  
  476.  
  477. Here the "parameter", the colour number, is "1" (or "3"), and is written
  478. in your source code as a simple number preceding the word FPENSET.
  479.  
  480. This looks very natural and simple, and indeed this simplicity is a very
  481. good feature of HeliOS, but a little more is happening than is apparent.
  482.  
  483. What actually happens is that the number "1" is stored on the stack until
  484. it is used by FPENSET, which leaves the stack empty.  This situation is
  485. represented by the "stack diagram", which you will see used throughout
  486. the HeliOS Dictionary definitions.  This is a means of representing what
  487. happens to the stack during the operation of a HeliOS Word.
  488.  
  489. In the case cited above we have a stack diagram as follows:
  490.  
  491.  
  492.                        n - - -
  493.  
  494.  
  495. The "n" represents the colour number which the word FPENSET expects to
  496. find placed on the stack.  The three "-" signs signify the computing
  497. process as FPENSET does its work, and the fact that there is no number
  498. afterwords means that FPENSET actually uses internally and removes its
  499. single parameter, leaving nothing on the stack itself.
  500.  
  501. The parameter to be passed to the subroutine is stored temporarily on
  502. the stack, the subroutine then removes it and, in this case, returns
  503. with the stack clear.
  504.  
  505. This method is crucial to HeliOS operation.  Several parameters can be
  506. passed to subroutines via the stack, as you will see in the examples
  507. given below.  The word GFXRECTFILL, for example, uses four parameters
  508. denoting the corners of a box to draw a filled rectangle.
  509.  
  510. Many subroutines use the stack to return parameters, and your program
  511. must constantly keep track of the stack to ensure that this process of
  512. passing parameters is kept in order.
  513.  
  514. The HeliOS words used to make ordinary arithmetic calculations all get
  515. their parameters from the stack, operate on them, and then return the
  516. result of the calculation on the stack.
  517.  
  518. In a simple addition two parameters are needed, and the result, which
  519. is a single parameter, is returned on the stack -
  520.  
  521.      3 5 +   add two numbers 3 and 5, leaving the result on the stack
  522.  
  523.      .       display on screen the value on the stack ( the "result" )
  524.  
  525. The stack diagrams of these two words would be:
  526.  
  527.     "+"         n1  n2  - - - n3
  528.  
  529.     "."             n3  - - -
  530.  
  531.  
  532. ---------------
  533. Using Variables
  534. ---------------
  535.  
  536. While HeliOS uses the stack for most of its short term parameter passing
  537. operations, ordinary memory can be used for data storage on a more long
  538. term basis.  Languages like BASIC and PASCAL use named variables to access
  539. the memory in which the data is stored without involving the programmer
  540. with the actual "physical" memory address, or indeed with "stacks".
  541.  
  542. HeliOS can do the same thing if required, and while the stack is much more
  543. efficient for most parameter passing (and gives HeliOS a significant speed
  544. advantage), there are many occasions where it is best to use variables.
  545.  
  546. A variable can be created using the word VARIABLE and data can be moved in
  547. and out using the two HeliOS words "!" (which is pronounced "store") and @
  548. (which is pronounced "fetch").
  549.  
  550. When a variable is created in HeliOS it always has to be initialised, but
  551. if no particular initial value is needed you can always set the initial
  552. value to zero.
  553.  
  554. A variable created in this way is stored in the dictionary.
  555.  
  556. For example,
  557.  
  558.     0 VARIABLE MILES
  559.  
  560. will create a VARIABLE called "MILES" initialised to zero.
  561.  
  562. In a similar manner,
  563.  
  564.     50 VARIABLE MILES
  565.  
  566. will create a VARIABLE called "MILES" and initialise it to 50.
  567.  
  568.  
  569. We can now get and display the memory contents referenced by the word
  570. "MILES" as follows:
  571.  
  572.     MILES @ .
  573.  
  574. (or a shorter version:   "MILES ?"  which does exactly the same thing.)
  575.  
  576.  
  577. What is actually happening here?
  578.  
  579.     MILES     \ Puts the address of the variable on the stack,
  580.                     \ or, more accurately, the address of the memory
  581.                     \ cell where the the value 50 is stored
  582.  
  583.     @    \ Gets the data stored at that memory address and
  584.                     \ puts it on the stack, having first removed the
  585.                     \ address from the stack
  586.  
  587.     .    \ Displays and removes the "top of stack" value
  588.  
  589. We have not specifically accessed memory numerically - we have just asked
  590. for the contents of the VARIABLE defined by the name "MILES".
  591.  
  592. This use of easy to remember words rather than numbers is a great help in
  593. writing easily understood code.
  594.  
  595.  
  596. In a similar manner we can store a value in a variable using "!" ("store")
  597.  
  598.     12 MILES !
  599.  
  600. will store the value 12 in the memory location defined by the word MILES.
  601.  
  602.  
  603. ---------------------------------------------
  604. A little note on 16-Bit and 32-Bit Addressing
  605. ---------------------------------------------
  606.  
  607. A computer deals with binary numbers, which are actually just like simple
  608. two-state "on or off" switches.  These are each said to contain one "bit"
  609. of information, and can only represent the numbers 1 and 0.
  610.  
  611. A single cell of memory contains an 8-bit number, which is a collection of
  612. 8 bits, and is called a "byte". This can represent a decimal number of up
  613. to "255", which is still a rather small unit of information.
  614.  
  615. Because a byte is such a small "chunk" of information, we often use a much
  616. larger unit of 16-bits, 2-bytes, which we call a "word".
  617.  
  618. Above this we have 32-bit numbers which are 2 "words" or 4 bytes in length,
  619. and these are often referred to as "long" or "longwords".
  620.  
  621. So....the data which we store is usually in the form of 1, 2, or 4 byte
  622. numbers.
  623.  
  624.  
  625. Computers use similar numbers to define positions in memory, often called
  626. memory "addresses", so that they know where to store and fetch information.
  627.  
  628. On a machine like the Amiga, memory is "addressed" by 32-bit, or 4-byte
  629. "long" numbers.
  630.  
  631. HeliOS uses a little "trick" to avoid the use of these very large numbers
  632. all the time.  It defines addresses within the HeliOS dictionary as 16-bit
  633. numbers and "internally" adds a further number to these addresses to get
  634. the true 32-bit address.  So HeliOS can use 16-bit addressing or 32-bit
  635. addressing depending on whether an address is in dictionary memory space.
  636.  
  637. Don't worry too much about these things for now; we simply mention them
  638. here to enable the code example later to be more fully comprehended.  We
  639. will give a couple of examples here to clarify how HeliOS defines different
  640. length numbers and addresses, but do not attempt to learn this now, and do
  641. not worry if you cannot follow all the explanation.
  642.  
  643.  
  644. ------------------------------------------------------------------
  645. The HeliOS Dictionary is a 16-bit addressed, 16-bit data structure
  646. ------------------------------------------------------------------
  647.  
  648. What does this "imposing" statement mean?
  649.  
  650. To keep things simple for now we should just point out that HeliOS uses
  651. 16-bit numbers for its standard mode of operation.  Numbers on the stack
  652. are stored as 16-bit "cells", and 32-bit numbers are stored as two of
  653. these standard cells.  HeliOS stores 8-bit numbers on the stack again in
  654. a 16-bit cell, but ignores the top byte of the number.
  655.  
  656. A 16-bit number is often referred to in HeliOS as a "single number".
  657.  
  658. A 32-bit number is often referred to in HeliOS as a "double number".
  659.  
  660. As well as using 16-bit data items as "standard", all memory addressing
  661. within the HeliOS dictionary memory space is usually specified by 16-bit
  662. numbers also (although any 16-bit HeliOS address can also be specified as
  663. a 32-bit address if required).
  664.  
  665. In general then, HeliOS, like traditional Forth, is largely concerned in
  666. its internal operations with 16-bit numbers.
  667.  
  668. Double word 32-bit addressing specifies a memory location directly as one
  669. large number. As its name implies, 4 bytes of storage are needed to handle
  670. this number.  This 32-bit addressing is always used in conjunction with
  671. Amiga library calls, and cannot be avoided.  A 32-bit address is stored
  672. on the HeliOS stack as two 16-bit numbers, but there are many HeliOS commands
  673. which treat this easily as one 32-bit entity.
  674.  
  675. A 32-bit address is often referred to as a "long" address, or a "longword"
  676. address.
  677.  
  678. 16-bit addressing is ONLY used to specify memory addresses within the main
  679. HeliOS dictionary. Remember always that this addressing technique specifies
  680. a memory location as an offset from a point of reference which is the start
  681. of the HeliOS dictionary.
  682.  
  683. Here are two HeliOS command words which translate between 16-bit and 32-bit
  684. addressing for any addresses within the HeliOS dictionary:
  685.  
  686. W>L ( a1 - - - l1 ) -> Converts a 16-bit address to a 32-bit address
  687.  
  688. L>W ( l1 - - - a1 ) -> Converts a 32-bit address to a 16-bit address
  689.  
  690. --------------------------------------------------------------
  691. How HeliOS specifies 16-bit and 32-bit addressing and numbers.
  692. --------------------------------------------------------------
  693.  
  694. Addressing can be very confusing and people often get mixed up with 16
  695. and 32 bit data values and 16 and 32 bit addresses.  To avoid confusion
  696. when using these differing quantities we need to use a regular notation.
  697.  
  698. HeliOS uses a standard notation of:
  699.  
  700.    a "D" prefix for double length data
  701.  
  702.    an "L" suffix for long addressing
  703.  
  704.  
  705. An example using VARIABLES may help clarify the matter:
  706.  
  707.  
  708. Both 16-bit and 32-bit data storage variables can be created as follows:
  709.  
  710.  
  711.  50 VARIABLE MILES
  712.  
  713.                Creates a 16-bit variable called 'MILES' and initialises
  714.                it to 50.
  715.  
  716.                This variable is referenced by a 16-bit address.
  717.                Use of the word 'MILES' puts a 16 bit address on the
  718.                stack, indicating the memory location where the number
  719.                50 is stored as a 16-bit number in the HeliOS dictionary
  720.                memory space.
  721.  
  722.  
  723.  50. DVARIABLE MILES
  724.  
  725.                Creates a 32-bit variable called 'MILES'. The full stop
  726.                after the "50" indicates that this is a 32-bit number.
  727.  
  728.                In this case the 32-bit data value is stored at a 16-bit
  729.                address, and use of the word "MILES" returns this 16-bit
  730.                address where the 32-bit number "50." is stored.
  731.  
  732.                Note that the number 50 itself could be stored in an
  733.                8-bit space: the data size refers to the storage space
  734.                and not the size of the actual number stored there.
  735.  
  736.                The D prefix signifies a double length data variable -
  737.                remember this, as it is the standard form of notation.
  738.  
  739.  
  740.  50 VARIABLEL MILES
  741.  
  742.                Creates a 16-bit variable called 'MILES' stored at a 
  743.                32-bit or Long address.  Use of the variable 'MILES' 
  744.                returns a 32-bit number on the stack representing the
  745.                longword address where the 16-bit value is stored.
  746.  
  747.                The L suffix signifies a long address, and again this is
  748.                a standard notation for "long" 32-bit addressing.
  749.  
  750.  
  751.  50. DVARIABLEL MILES
  752.  
  753.                Creates a 32-bit data variable stored at a 32-bit address.
  754.  
  755.                Note the 32-bit data indicated by the "." after the "50"
  756.                and the "D" prefix to indicate a 32-bit data variable.
  757.  
  758.                Note again the use of the "L" suffix to indicate the long
  759.                addressing mode.
  760.  
  761.                   
  762. The above example illustrates standard HeliOS notation, which you should 
  763. become familiar with as soon as possible.
  764.  
  765. Remember that the D prefix always relates to double length data and the
  766. L suffix relates to long addresses.
  767.  
  768. It is important to remember here that variables within the main HeliOS
  769. dictionary can actually be 16-bit addressed or 32-bit addressed.  Those
  770. given 16-bit addresses can be converted to 32-bit addresses using the
  771. HeliOS Word "W>L" ("word-to-longword").  An address thus converted may be,
  772. in turn, restored to 16-bit form using the reverse operation "L>W".
  773.  
  774. Data values can easily be converted from single to double size using the
  775. word "S>D" ("single-to-double"), but values can only be converted from
  776. double to single if they are less than 16-bit in "numerical" size.
  777.  
  778. Unsigned single numbers can be converted to double numbers by simply adding
  779. a zero to the stack, since this zero represents the high word of the new
  780. 32-bit value.
  781.  
  782. It is important to handle parameter passing (via the stack) correctly if
  783. your programs are to run satisfactorily, so you have to be careful to use
  784. 16 and 32-bit values and addresses properly.  If a subroutine expects a
  785. double word parameter (4 bytes) passed on the stack, the computer will
  786. probably crash if you only pass a single word parameter of 2 bytes!
  787.  
  788.  
  789. ---------------------------------------
  790. Using "Text Strings" in HeliOS programs
  791. ---------------------------------------
  792.  
  793. The term "String" is used in relation to text storage in memory. Since
  794. computers only deal with numbers we have to represent text as a "string"
  795. of numeric codes in memory.
  796.  
  797. Each text character is defined by a numeric code called an "ASCII" value,
  798. which is a standard code used for representing letters as numbers in the
  799. computer's memory.
  800.  
  801. A series of continuous bytes in memory which represent text ("ASCII")
  802. characters make up a text "string".
  803.  
  804. Strings are handled either as "counted strings", which are always stored
  805. along with a number indicating their length, or "null terminated strings"
  806. which simply carry on in memory until a "0" character is encountered.
  807.  
  808. In both cases a memory address is used to specify the first byte of the
  809. string, and this number is used to manipulate the string. As with numeric
  810. data a string "address pointer" can be a simple number on the stack, or 
  811. may be "named" like a variable.
  812.  
  813. The first byte of a counted string is always called the "count byte" and 
  814. is a number representing the total number of text characters in the string. 
  815.  
  816. In the case of the "null terminated" string the first byte of the string 
  817. is simply the first character of the string itself, which continues on in 
  818. memory until a null value "0" occurs: hence its name.  
  819.  
  820. Counted strings have limited length, since the single "count" byte has a
  821. maximum value of 255.  Null terminated strings, on the other hand, can be 
  822. of any length.
  823.  
  824. Traditionally Forth used counted strings, but the Amiga operating system
  825. uses null terminated strings.  HeliOS has comprehensive support for
  826. both types, as well as easy conversion from one to the other.
  827.  
  828. HeliOS has an extra useful feature in that counted strings all have
  829. a null terminator as well. To access a counted string as "null terminated"
  830. all you have to do is increment the address of the string by one, thus 
  831. moving forward past the initial "count" byte to the first character.
  832.  
  833. HeliOS has a large number of string handling routines, many of which
  834. handle either 16-bit or 32-bit addressing. As a general rule, handle all
  835. strings as 16-bit addressed in simple programs unless you need to pass the
  836. string to an Amiga library function.  In this case you can easily convert
  837. to a 32-bit address using "W>L" as required.
  838.  
  839. --------------------------------------------------------------
  840. A very simple and useful HeliOS string handling word - "LIT$".
  841. --------------------------------------------------------------
  842.  
  843. Using LIT$ within Colon definitions
  844.  
  845. LIT$ is used within a colon definition to allow compilation of a counted 
  846. string within your program code.  The text string must be enclosed between
  847. two dollar ("$") characters, as this example shows:
  848.  
  849.   : PRESSMESSAGE   LIT$ $Press SPACE-BAR To Continue$ ;
  850.  
  851. This example creates a new word PRESSMESSAGE, which employs "LIT$" to store
  852. the text between the two dollar characters ("Press SPACE-BAR To continue")
  853. within the dictionary.  When you later use the word PRESSMESSAGE the 16-bit
  854. address of the string is returned on the stack.  It can then, for example,
  855. be printed out to the screen using the word "$." in another word as follows:
  856.  
  857.   : SHOWPRESMESSAGE   PRESSMESSAGE $. ;
  858.  
  859. You will find this little word "LIT$" VERY useful indeed.  We use it in 
  860. the example program below, and you should learn to use it yourself in your
  861. own programs as soon as possible.
  862.  
  863.  
  864. -------------------------------------
  865. General INPUT and OUTPUT using HeliOS
  866. -------------------------------------
  867.  
  868. Obtaining User Input
  869.  
  870. HeliOS has a general purpose input word "KEY". This word causes a program 
  871. to wait for an input event to occur.  Input events include keyboard entry, 
  872. mouse button depression, mouse movement, gadget selection, menu selection 
  873. or ticker activation.  We use the word "KEY" because traditional Forth used 
  874. this word, although it only accessed keyboard events, unlike the more 
  875. extended HeliOS version which handles ALL events.
  876.  
  877. The user input word "KEY" will report input events from whatever active 
  878. window YOU specify.  You can designate ANY window as the current input
  879. window using the HeliOS special word "MAKEINWINDOW".  This is an
  880. immensely powerful and important word, as it includes within itself a
  881. whole "sub-program" which in any other Amiga language you would have to
  882. write for yourself.  This "sub-program" sets up a special task to monitor
  883. and translate all input events, and has many very sophisticated features
  884. unique to HeliOS.  All this power translates, from your point of view, to 
  885. a very easy use of the single word "KEY" - all the hard work is done for 
  886. you!
  887.  
  888.  
  889. -------------------------------------------------
  890. Sending Output to the User via the screen display
  891. -------------------------------------------------
  892.  
  893. There are two basic types of screen text output - console output and graphic
  894. text output.  
  895.  
  896. Text characters are usually written to console windows in streams, which 
  897. have full scrolling, cursor movement, and text formatting facilities etc.  
  898.  
  899. In general all dynamic, changing text output is handled by "console" type
  900. displays.
  901.  
  902. Graphic text output does not have these "text control" features and all 
  903. text is placed on the screen as a static graphic "drawing".  This means 
  904. that, for example, text can only be deleted by overwriting the screen area 
  905. occupied by the graphic image of the text.  
  906.  
  907. In general graphic text output is used for "painting" a graphic display with
  908. static text.
  909.  
  910. Both kinds of text are fully supported by HeliOS, but the following
  911. simple examples use "console" text output for simplicity.  Note that this
  912. console output is not always simple on the Amiga, and in other languages
  913. quite a lot of programming is required to set up any console output.
  914. HeliOS is unique in the power of its automated functions, and, as you will 
  915. see, console text output has been made very powerful and easy.
  916.  
  917. As a matter of interest, HeliOS has two powerful sub-programs which
  918. fully automate the setting up of all console text output and graphical
  919. operations within ANY designated window on ANY screen.
  920.  
  921. Quite large programs would have to be written by YOU in any other language
  922. to achieve this functionality of HeliOS, which requires you to use just ONE 
  923. word to set up each sub-program:
  924.  
  925.  "MAKOUTWINDOW"   - sets up a VERY sophisticated console handling system
  926.                     with TEN automated text "streams".
  927.  
  928.  "MAKEGFXWINDOW"  - sets up an automated graphics library handling system
  929.                     with single word operators for most graphic functions.
  930.  
  931. Our final example program below will show you how to use these functions.
  932.  
  933.  
  934.                     -------------------------------------
  935.                     A FIRST TUTORIAL PROGRAMMING EXERCISE
  936.                     -------------------------------------
  937.  
  938. Our tutorial program will start with a line of code which clears all words
  939. from the user dictionary, leaving just the CORE vocabulary -
  940.  
  941.  
  942.   FORGET **CORE**          \ Get rid of any old USER defined words
  943.  
  944.  
  945. The "\" character denotes an "end of line comment", and anything following 
  946. this is ignored by the compiler.  Always add plenty of descriptive comments 
  947. to your code in this way, so that you know what is going on.
  948.  
  949. Note here that ALL words in HeliOS source code should have a space before
  950. and after them. This is absolutely vital, and note that a space is also
  951. needed both before and after the "\" character, because this is also a
  952. HeliOS Word.
  953.  
  954. To summarise these points, the above line of code has:
  955.  
  956.     At least one space
  957.  
  958.     The word "FORGET"
  959.  
  960.     At least one space
  961.  
  962.     The word "**CORE**" telling FORGET to clear all words back to CORE
  963.  
  964.     At least one space
  965.  
  966.     The word "\" which tells us that the rest of the line is a comment
  967.  
  968.     At least one space
  969.  
  970.     The words "Get rid of any old USER defined words"  - the comment
  971.  
  972.  
  973. Now we will add a "colon definition" to our program.
  974.  
  975.  
  976.  
  977.   FORGET **CORE**                \ Get rid of any old USER defined words
  978.  
  979.   : SAYHELLO ." HELLO WORLD" ;   \ Make a word called SAYHELLO
  980.  
  981.  
  982. The colon definition above will create a new subroutine called SAYHELLO.
  983.  
  984. Let us look at it's structure. It has -
  985.  
  986.     At least one space
  987.  
  988.     A ":" to start the definition
  989.  
  990.     At least one space
  991.  
  992.     A descriptive label, "SAYHELLO"
  993.  
  994.     At least one space
  995.  
  996.     The definition " ." HELLO WORLD" "
  997.  
  998.     At least one space
  999.  
  1000.     A ";" to finish the definition
  1001.  
  1002.     At least one space
  1003.  
  1004.     A "\" which tells us that the rest of the line is a comment
  1005.  
  1006.     At least one space
  1007.  
  1008.     The words "Make a word called SAYHELLO" - the comment itself 
  1009.  
  1010.  
  1011. We now have a small program:
  1012.  
  1013.  
  1014.   FORGET **CORE**               \ Dispose of any old USER defined words
  1015.  
  1016.   : SAYHELLO ." HELLO WORLD" ;  \ Make a subroutine called SAYHELLO
  1017.  
  1018.  
  1019.  
  1020. The next thing of interest is the definition ." HELLO WORLD".
  1021.  
  1022.  
  1023. This can be split into three parts as follows.
  1024.  
  1025. <SPACE>   ."   <SPACE>   HELLO WORLD      "
  1026.  
  1027. The first part is the HeliOS word ." which tells the HeliOS system to output
  1028. to the screen the words following it up to the next " character.
  1029.  
  1030. The second part is the expression HELLO WORLD, which is the message we want
  1031. to display.
  1032.  
  1033. The third part is the quote character " which tells the HeliOS system that
  1034. our enclosed quotation has ended.  The double quote " is not a HeliOS WORD
  1035. and does not need a space before it.  It is called a delimiter and merely
  1036. acts to delimit the end of an enclosed text message "string".
  1037.  
  1038. To use the new word (subroutine) all we need to do is either type it at
  1039. the command line after compiling our program, or include it in our program
  1040. code after the definition.
  1041.  
  1042.  
  1043. --------------------------------------
  1044. Entering and compiling our new program
  1045. --------------------------------------
  1046.  
  1047. There are two ways of entering code. We can either use an editor or we can
  1048. type in code at the the command line. The editor option is perhaps better
  1049. in most cases because code can be saved to and loaded from disk files.
  1050.  
  1051. The command line has a circular "history" buffer and is useful for testing
  1052. small fragments of code which are being continually modified.  It is very
  1053. quick for small code testing jobs, but cannot be saved to disk.
  1054.  
  1055.  
  1056. We will use an editor in this tutorial example, as follows:
  1057.  
  1058. 1.  Load HeliOS: the interactive screen appears at once.
  1059.  
  1060. 2.  Click the "Ed 1" button at the top of the screen to enter "Editor 1".
  1061.  
  1062. 3.  Now type in the following code -
  1063.  
  1064. ( N.B.
  1065.  
  1066.   This text was intended to be used from a printed page.
  1067.  
  1068.   If you are using this text in the form of a disk file, you may already
  1069.   be viewing it in one of the HeliOS editors.
  1070.  
  1071.   In this case you can simply run the sections of code directly without
  1072.   having to type them in. )
  1073.  
  1074.  
  1075.    FORGET **CORE**              \ Dispose of any USER defined words
  1076.  
  1077.    : SAYHELLO ." HELLO WORLD" ; \ Make a word called SAYHELLO
  1078.  
  1079.    SAYHELLO                     \ Use the new word we have created
  1080.  
  1081.    WAITSPACE                    \ Wait for the space bar to be pressed
  1082.  
  1083. 4. Compile the section of code.
  1084.  
  1085. This action will take you into the Interpreter and run the program.
  1086.  
  1087. This is a program which actually does something.  It will print to the
  1088. screen the message "HELLO WORLD".  Note that you can now type SAYHELLO
  1089. at the command line and the message "HELLO WORLD" will appear on screen.
  1090.  
  1091. Note also that you can use the up-arrow cursor key to bring back all the
  1092. previously typed command lines and reuse them - this makes use of the
  1093. circular command line "history" buffer mentioned above.
  1094.  
  1095. The next thing to do, perhaps, is save the code to a disk file, so.......
  1096.  
  1097.  
  1098. 5.  Repeat step 2 to reenter the Editor, then select 'Save As' from
  1099.     the 'Load/Save' menu to access the HeliOS File Requester and
  1100.     save the file.
  1101.  
  1102.     Note that each time you resave a file with the same name as before
  1103.     HeliOS will create a backup file for you automatically.
  1104.  
  1105. Having made a small working program we can now start to do some more
  1106. interesting things with it.
  1107.  
  1108. Listed below are a number of variations on our program for you to try.
  1109.  
  1110. Use the editor again to modify the code already entered, then use the
  1111. method outlined above to save and execute your code.
  1112.  
  1113.  
  1114. Try each of the following variations:
  1115.  
  1116.   ( Note that you can omit the comments if you like )
  1117.  
  1118.  
  1119.   : SAYHELLO       \ This version changes the output text position
  1120.  
  1121.   10 10 CURPUT     \ Set the text output position ("PUT" the "CURSOR")
  1122.  
  1123.   ." HELLO WORLD"  \ Say hello
  1124.   ;
  1125.  
  1126.  
  1127.   : SAYHELLO       \ This changes the output text position and colour
  1128.  
  1129.   3 FPENSET        \ Set the foreground pen - text colour
  1130.   1 BPENSET        \ Set the background pen - text background
  1131.   10 10 CURPUT     \ Set the text output position ("PUT" the "CURSOR")
  1132.  
  1133.   ." HELLO WORLD"  \ Say hello
  1134.   ;
  1135.  
  1136.  
  1137.   : SAYHELLO              \ This displays the message 4 times in line
  1138.  
  1139.   4 0
  1140.   DO                      \ Loop 4 times
  1141.     ." HELLO WORLD"       \ Say hello
  1142.     SPACE                 \ Put a space between messages
  1143.   LOOP
  1144.   ;
  1145.  
  1146.  
  1147.  
  1148.   : SAYHELLO            \ To display the message 4 times on new lines
  1149.  
  1150.   4 0 
  1151.   DO                    \ Loop 4 times
  1152.     CR                  \ "Carriage Return" =  Go to start of next line
  1153.     ." HELLO WORLD"     \ Say hello
  1154.   LOOP
  1155.   ;
  1156.  
  1157.  
  1158.   Now for a more interesting one........
  1159.  
  1160.  
  1161.   : SAYHELLO   \ This repeats the message 4 times on new lines in a box
  1162.  
  1163.   3 FPENSET    \  Set the foreground pen - text colour
  1164.   1 BPENSET    \  Set the background pen - text background
  1165.  
  1166.   1 GFXSETAPEN \  Set the graphics drawing colour (box colour)
  1167.   2 GFXSETOPEN \  Set the graphics outline pen colour (box outline)
  1168.  
  1169.   1 GFXOUTLINE \  Switch on graphics OUTLINE mode
  1170.  
  1171.   10           \  "x" pos, in pixels of the box's top left hand corner,
  1172.                \  measured from top left hand corner of screen
  1173.   45           \ Top left "y" pos
  1174.   150          \ Bottom right "x" pos
  1175.   90           \ Bottom right "y" pos
  1176.   GFXRECTFILL  \ Draw a filled rectangle (draw box)
  1177.  
  1178.   0 GFXOUTLINE \ Switch off graphics OUTLINE mode
  1179.  
  1180.   4 0
  1181.   DO                 \ Loop 4 times
  1182.     CR               \ "Carriage Return" =  Go to start of next line
  1183.     4 CURFW          \ Move the "CURSOR FORWARD" to give a margin
  1184.     ." HELLO WORLD"  \ Say Hello
  1185.   LOOP
  1186.   ;
  1187.  
  1188.  
  1189.   And now an even more interesting one........
  1190.  
  1191.  
  1192.   : SAYHELLO     \ This repeats the message 4 times on new lines in a box
  1193.  
  1194.   3 FPENSET      \ Set the foreground pen - text colour
  1195.   1 BPENSET      \ Set the background pen - text background
  1196.  
  1197.   1 GFXSETAPEN   \ Set the graphic drawing colour (box colour)
  1198.   2 GFXSETOPEN   \ Set the graphics outline pen colour (box outline)
  1199.   1 GFXOUTLINE   \ Switch on graphics OUTLINE mode
  1200.  
  1201.   10             \ "x" pos, in pixels, the box's top left hand corner,
  1202.                  \ measured from top left hand corner of screen
  1203.   45             \ Top left "y" pos
  1204.   150            \ Bottom right "x" pos
  1205.   90             \ Bottom right "y" pos
  1206.   GFXRECTFILL    \ Draw a filled rectangle (draw box)
  1207.  
  1208.   0 GFXOUTLINE   \ Switch off graphics OUTLINE mode
  1209.  
  1210.   4 0
  1211.   DO                 \ Loop 4 times
  1212.     4                \ Start at 4th position on line
  1213.     I 2 +            \ Start at 2nd line + LOOP INDEX
  1214.     CURPUT           \ PUT the CURSOR
  1215.     ." This is line" \ Print "This is line"
  1216.     I 1+             \ Increment the LOOP INDEX + 1 which is stored
  1217.                      \ on the stack, (the index starts at 0)
  1218.     .                \ Print the index number (stored on the stack)
  1219.   LOOP
  1220.   ;
  1221.  
  1222.  
  1223. **************************************************************************
  1224.  
  1225. ----------------------------------------
  1226. Using Amiga Libraries from within HeliOS
  1227. ----------------------------------------
  1228.  
  1229. Amiga Libraries are special code modules which are provided to help you
  1230. with various programming tasks, and are very simple to use.  Libraries are
  1231. either present within the Amiga ROM (Read Only Memory), or may be loaded
  1232. from disk.
  1233.  
  1234. The method of accessing a library is:
  1235.  
  1236.  1.  OPEN the library       The Amiga loads and prepares it for use
  1237.  
  1238.  2.  CALL library routines  You will need a reference book for definitions
  1239.  
  1240.  4.  CLOSE the library      When you have finished with it
  1241.  
  1242.  
  1243. Many Amiga library routines are included in HeliOS as part of the CORE
  1244. dictionary.  These functions are pre-written "interfaces" to specific Amiga
  1245. library calls and do not require you to address the library directly.
  1246.  
  1247. In addition, the main and most useful libraries are automatically opened for
  1248. you when HeliOS starts up and closed when HeliOS closes down.
  1249.  
  1250. These are the DOS, EXEC, GRAPHICS, LAYERS, and INTUITION libraries.
  1251.  
  1252. If you do have to open a library yourself there is a simple to use HeliOS
  1253. word called OPENLIB, which opens a library and returns the 32-bit library 
  1254. base address on the stack as follows:
  1255.  
  1256. First, in our example we are going to open "diskfont.library", so we need a
  1257. DVARIABLE to store the library base address when we have opened it.
  1258.  
  1259.  D0 DVARIABLE DFONTBASE  \ Create a 32-bit variable DFONTBASE
  1260.  
  1261. Now open the library.........
  1262.  
  1263.  LIT$ $diskfont.library$    \ Put counted library name string on stack
  1264.  0                          \ Put library revision number on stack
  1265.  OPENLIB                    \ OPEN the library
  1266.  DFONTBASE D!               \ Store the library handle
  1267.  
  1268.  
  1269. Having done this, always check to see that the new base variable is not
  1270. still zero, in which case the library has failed to open for some reason
  1271. and you need to sort out the problem.
  1272.  
  1273.  
  1274. Closing a library:
  1275.  
  1276. First remember that you only need to close libraries that you yourself
  1277. have specifically opened.  You do not need to close the standard libraries
  1278. handled for you by HeliOS system.
  1279.  
  1280. To close a library put the library base address on the stack and use the 
  1281. word CLOSELIB like this:
  1282.  
  1283.  
  1284.   DFONTBASE D@ CLOSELIB
  1285.  
  1286.  
  1287. That's all there is to it...................easy!
  1288.  
  1289.  
  1290.  
  1291. When a library is open and you want to use it, you need to know 3 things:
  1292.  
  1293. 1.      What is the library base offset for the routine you wish to call?
  1294.         This is found from Amiga documentation and will always be a negative
  1295.         number.
  1296.  
  1297. 2.      What "parameters" does that library call require before using it?
  1298.  
  1299. 3.      What results are returned after completion?
  1300.  
  1301. These details are also found in Amiga library documentation.
  1302.  
  1303.  
  1304. So assuming that you know all about the routine you are calling and its
  1305. start-up parameters, you now need to know what to do with the start-up
  1306. parameters when calling a library from HeliOS.
  1307.  
  1308. HeliOS is very close to assembly language in operation, so it handles
  1309. library calling parameters in a manner closely reflecting the way it is
  1310. done in assembly language.
  1311.  
  1312. If you look at the Amiga library documentation you will see that there are
  1313. instructions for assembly language library calls, telling the programmer in
  1314. which 680xx microprocessor registers to store parameters.
  1315.  
  1316. You can gather from this that in assembly language you store parameters
  1317. directly into the registers within the 680xx microprocessor before calling
  1318. a library.  The results of library calls are also stored in these 680xx
  1319. registers when the library call has been completed.
  1320.  
  1321. Don't worry if this sounds difficult - it is actually very easy!
  1322.  
  1323. The 680xx has a set of 8 ADDRESS registers, labelled A0-A7, and a set of
  1324. 8 DATA registers, labelled D0-D7. These registers are all 32-bit registers.
  1325.  
  1326.  
  1327. Your library documentation will say things like
  1328.  
  1329. Put Buffer Address into register A0
  1330. Put Buffer Length into register D0
  1331. Call Library
  1332. Read result of call from register D0
  1333.  
  1334.  
  1335. To translate this type of operation into HeliOS is very easy because
  1336. you have a set of DUMMY REGISTERS in which to store your parameters and
  1337. read your results.
  1338.  
  1339. The DUMMY ADDRESS REGISTERS are accessed as double number 32-bit variables
  1340. by putting the register number you require on the HeliOS stack and then
  1341. using the word AREG to return the variable address.
  1342.  
  1343. The same method applies to DUMMY DATA REGISTERS but this time you use the
  1344. word DREG.
  1345.  
  1346. When HeliOS calls a library for you, using the HeliOS Word LIBRARY,
  1347. it simply unloads the dummy registers into the actual 680xx processor
  1348. registers, calls the library, then unloads the 680xx registers back into
  1349. the dummy registers.  This is very useful because it means that the values
  1350. in the dummy registers are retained for your use until the next time you
  1351. make a library call.
  1352.  
  1353.  
  1354. To carry out the example library call given above you would:
  1355.  
  1356.  Put Buffer Address into DUMMY register A0
  1357.  Put Buffer Length into DUMMY  register D0
  1358.  Call Library
  1359.  Read result of call from DUMMY register D0
  1360.  
  1361.  
  1362. To do this in Helios code you might write:
  1363.  
  1364.  
  1365.  BUFFERADDRESS D@   \ Get buffer address onto stack
  1366.  0 AREG D!          \ Store it in DUMMY ADDRESS REGISTER A0
  1367.  
  1368.  BUFFERLENGTH D@    \ Get buffer length onto stack
  1369.  0 DREG D!          \ Store it in DUMMY DATA REGISTER D0
  1370.  
  1371.  LIBRARYBASE        \ Put address of Library base store onto stack
  1372.  -64                \ Get library offset onto stack
  1373.  LIBRARY            \ Call library
  1374.  
  1375.  0 DREG D@          \ Get result from DUMMY DATA REGISTER D0 onto stack
  1376.  
  1377. Remember, the dummy registers will always directly reflect their 680xx
  1378. counterparts before and after the library call.
  1379.  
  1380. The word LIBRARY which makes the call is not at all complicated, you simply
  1381. put the name of the variable where the library base address is stored onto
  1382. the stack, followed by the library routine offset, then use the word
  1383. LIBRARY exactly as shown above.
  1384.  
  1385. Note that it is not the library base pointer itself that is used by the
  1386. word "LIBRARY" but the 16-bit storage variable address.
  1387.  
  1388. That is all there is to calling Amiga libraries, except for one thing which
  1389. makes it even easier!  In the above code we have accessed the result of the
  1390. library call, in register D0, quite correctly using "0 DREG D@".  Because
  1391. this sequence is used very often we have included an easy and quicker single
  1392. word alternative. Instead of typing "0 DREG D@" you can simply type the one
  1393. word "D0RESULT" to get the value in DUMMY REGISTER D0. 
  1394.  
  1395.  
  1396. *****************************************************************************
  1397.  
  1398. ----------------------------------------------------
  1399. General procedures for Starting and Closing programs
  1400. ----------------------------------------------------
  1401.  
  1402. It is a good idea to stick to a regular procedure (hopefully a good one)
  1403. when writing all your programs.  Especially in code which starts and closes
  1404. down your programs, it is possible and desirable to use a standard set of
  1405. prewritten subroutines which can be modified as required.
  1406.  
  1407. There are several rules that you should follow to produce good, safe code-
  1408.  
  1409. 1. Always mirror opening and closing calls.
  1410. 2. Always have ONE universal and thorough exit point.
  1411. 3. Always make sure you close down everything you open, especially memory.
  1412. 4. Always initialise variables correctly.
  1413. 5. Always check memory available before and after using a program
  1414.    - if you are losing memory something is very wrong.
  1415. 6. Always arrange your own output screen/window for serious programs 
  1416.    - you can't use the interactive HeliOS window in stand-alone compiled
  1417.      code......because it won't be there!
  1418.  
  1419.  
  1420. It is a good idea to use two standard start-up and close-down words for all
  1421. your programs. Any special functions needed to start particular programs may
  1422. be handled as single extra subroutine calls rather than all the code being
  1423. included directly in your main startup subroutine.
  1424.  
  1425.  
  1426. We include below simple source code for a program which:
  1427.  
  1428.   Has a simple structured "startup" word definition and a corresponding
  1429.   "closedown" routine.  You can modify these for your own purposes and it
  1430.   would be a good idea to use them as a basis for all your early programs.
  1431.  
  1432.   Opens a custom screen
  1433.  
  1434.   Opens a window on the new screen
  1435.  
  1436.   Sets up graphic output to the new window and draws some graphics,
  1437.   including "graphic text"
  1438.  
  1439.   Sets up console text output in the new window and prints some text
  1440.  
  1441.   Sets up user input from the new window and waits for <SPACE> to
  1442.   be pressed.
  1443.  
  1444.   Uses an Amiga library call to show how it is done.
  1445.  
  1446.   Uses most of the things we have been discussing above......
  1447.  
  1448.  
  1449. You will be surprised, perhaps, to see how easy all this is, and certainly
  1450. you will be amazed how easy it is if you have used other Amiga programming
  1451. languages which require you to do an enormous amount more preparatory work.
  1452.  
  1453.  
  1454. Note:
  1455.  
  1456.   The following program is provided as a disk file called "TutorialProg.Src".
  1457.  
  1458.   Load this program into the HeliOS editor, as described for the small
  1459.   tutorial programs given earlier, then compile and run it.
  1460.  
  1461.  
  1462. A typical start up program section might be as follows-
  1463.  
  1464.   FORGET **CORE**           \ Clear the user dictionary
  1465.  
  1466.   D0 DVARIABLE SCREEN       \ New Screen handle storage variable
  1467.   D0 DVARIABLE WINDOW       \ Window handle store
  1468.  
  1469.   D0 DVARIABLE BITMAP       \ Variables to store useful values, which.
  1470.   D0 DVARIABLE RASTPORT     \ are collected at startup time in case of 
  1471.   D0 DVARIABLE VIEW         \ the need to use them later in graphics
  1472.   D0 DVARIABLE VIEWPORT     \ related functions.
  1473.  
  1474.  
  1475.   \ OPENSYSTEM - Opens a screen and a window and sets up Input/Output.
  1476.   \              Includes an example of a library call for you to see
  1477.   \              Returns "1" on the stack for success and "0" for failure
  1478.  
  1479.  
  1480.   : OPENSYSTEM              \ Start a colon definition, the new word is
  1481.                             \ called, appropriately, "OPENSYSTEM"
  1482.  
  1483.    TIMEOFF                  \ Disable the time display in the HeliOS screen
  1484.  
  1485.    0 HISTORY                \ Disable the line editor's circular buffer
  1486.  
  1487.    1 BAKSET                 \ Enable creation of Backup files on all disk
  1488.                             \ SAVE operations - a useful safety feature
  1489.  
  1490.    \ These are all "general purpose" startup operations often used
  1491.  
  1492.  
  1493.    1 STDSCREEN              \ Initialises a standard NewScreen structure
  1494.                             \   and sets Hires mode
  1495.  
  1496.    LIT$ $Tutorial Screen$   \ Specify the screen title bar text
  1497.  
  1498.    640 250                  \ Specify screen width and height
  1499.  
  1500.    3                        \ Depth of screen = number of bit planes
  1501.  
  1502.    OPENSCREEN               \ Open a screen using the initialised structure
  1503.  
  1504.    SCREEN D!                \ Store the screen handle/pointer 
  1505.  
  1506.    SCREEN D@                \ Get SCREEN 32-bit pointer onto stack
  1507.  
  1508.    
  1509.    D0>                      \ Test if SCREEN is greater than zero
  1510.                             \ This checks to see if screen opened OK
  1511.                             \ If SCREEN is zero we have trouble.......
  1512.  
  1513.    IF                       \ If SCREEN is not zero we are OK.........
  1514.  
  1515.  
  1516.       SCREEN D@             \ Get 32-bit pointer to screen
  1517.  
  1518.       44.                   \ Put double length number 44 on stack
  1519.  
  1520.       D+                    \ Add this to screen pointer to give
  1521.                             \  ViewPort pointer
  1522.  
  1523.       VIEWPORT D!           \ Store the ViewPort for the new screen 
  1524.  
  1525.       STDWINDOW             \ Initialise a standard NewWindow structure
  1526.  
  1527.       HFWINDOW              \ Modify the standard window for it to appear
  1528.                             \ on the HeliOS Screen
  1529.  
  1530.       SCREEN D@             \ Get new screen again
  1531.  
  1532.       WINDOWSTRUCT          \ Returns 16-bit pointer to NewWindow 
  1533.  
  1534.       30 +                  \ Add 30 to this
  1535.  
  1536.       D!                    \ Store screen pointer into NewWindow structure
  1537.  
  1538.       LIT$ $Tutorial Window$ \ Title bar text for window
  1539.  
  1540.       0 12 640 238          \ Guess what....Window dimensions!
  1541.       3                     \ 3 BitPlanes
  1542.       0                     \ No SUPERBITMAP
  1543.       OPENWINDOW            \ Open the new window
  1544.  
  1545.       WINDOW D!             \ and store window pointer/handle
  1546.  
  1547.       WINDOW D@             \ Check if opened OK, like screen above
  1548.  
  1549.       D0>                   \ See "screen open" check above........
  1550.  
  1551.       IF
  1552.  
  1553.         WINDOW D@
  1554.         MAKEGFXWINDOW       \ Enable graphics in this window
  1555.  
  1556.         WINDOW D@ 
  1557.         MAKEOUTWINDOW       \ Enable text output to this window
  1558.     
  1559.         WINDOW D@ 
  1560.         MAKEINWINDOW        \ Enable user input from this window
  1561.  
  1562.         WINDOW D@           \ Get Window pointer
  1563.  
  1564.         50. D+              \ Add 50 to Window Pointer to get RastPort
  1565.  
  1566.         D@L                 \ Get RASTPORT pointer
  1567.  
  1568.         RASTPORT D!         \ Get Window's RastPort, and store it in
  1569.                             \ variable RASTPORT
  1570.  
  1571.         RASTPORT D@ 
  1572.         4. D+ D@L 
  1573.         BITMAP D!           \ Get the bitmap from the stored RastPort
  1574.  
  1575.         INTUBASE            \ Put on the stack the 16-bit address 
  1576.                             \  where the 32-bit pointer to Intuition
  1577.                             \  library base is stored
  1578.  
  1579.         -294                \ Put on the stack the offset of the library
  1580.                             \  call "ViewAddress"
  1581.  
  1582.         LIBRARY             \ Call Intuition Library function to get 
  1583.                             \ VIEW pointer
  1584.  
  1585.         D0RESULT            \ Get dummy register D0 value which is the 
  1586.                         \   View address returned from the library call 
  1587.  
  1588.         VIEW D!             \ Store pointer in variable VIEW
  1589.  
  1590.         1                   \ Put value "1" on stack to indicate that
  1591.                             \ everything opened OK 
  1592.      ELSE
  1593.         0                   \ Put "0" on stack to indicate failure
  1594.      THEN 
  1595.    ELSE
  1596.      0                      \ Put "0" on stack to indicate failure
  1597.    THEN
  1598.    ;                        \ End of Colon Definition
  1599.  
  1600.  
  1601.   \ In a similar manner we have a defined a HeliOS word for the related
  1602.   \ close down routine -
  1603.  
  1604.  
  1605.    : CLOSESYSTEM               \ Start the colon definition
  1606.  
  1607.    FORTHINWINDOW               \ Redirect the input and output from
  1608.    FORTHOUTWINDOW              \ program's window back to the HeliOS
  1609.    FWINDOW MAKEGFXWINDOW       \ interactive environment
  1610.  
  1611.    WINDOW D@                   \ Get contents of window handle store
  1612.    DFLAG                       \ Check and if Non-Zero put 1 on stack else
  1613.                                \ put 0 on stack above window handle
  1614.  
  1615.          IF                    \ If window is open, ie handle is non zero
  1616.            CLOSEWINDOW         \ Close it
  1617.            WINDOW D0!          \ then set store to zero
  1618.          ELSE
  1619.             DDROP              \ else cleanup stack (drop window handle)
  1620.          THEN                  \ end of If/Then structure
  1621.  
  1622.    SCREEN D@                   \ Look at screen handle
  1623.    DFLAG IF                    \ If it is open......
  1624.            CLOSESCREEN
  1625.            SCREEN D0!
  1626.          ELSE
  1627.            DDROP                
  1628.          THEN
  1629.  
  1630.    TIMEON                      \ Enable time display for the 
  1631.                                \ HeliOS screen before exiting
  1632.    ;                           \ End of colon definition
  1633.  
  1634.  
  1635.     \ Now we can use these functions in a small program:
  1636.  
  1637.  
  1638.   : TUTORIALPROGRAM
  1639.  
  1640.   OPENSYSTEM                        \ Open environment, returning 1 or 0
  1641.                                     \ indicating success or failure
  1642.  
  1643.   IF                                \ If 1 is returned, for "success"
  1644.    
  1645.     1 GFXSETOPEN                    \ Set graphics outline pen colour to 1
  1646.  
  1647.     1 GFXOUTLINE                    \ Switch on graphics OUTLINE mode
  1648.  
  1649.     2 GFXSETAPEN                    \ Set graphics pen to "2" for circle
  1650.  
  1651.     400 160 80 40                   \ Circle coordinates
  1652.  
  1653.     GFXAREAELLIPSE                  \ Draw circle into off screen buffer
  1654.  
  1655.     GFXAREAEND                      \ Render circle to screen
  1656.  
  1657.     0 GFXOUTLINE                    \ Switch off graphics OUTLINE mode
  1658.  
  1659.     3 GFXSETAPEN                    \ Set graphics pen to "3" for text
  1660.  
  1661.     100 200 GFXMOVE                 \ Set graphics pen position
  1662.  
  1663.     LIT$ $This is graphic text$     \ Text string
  1664.  
  1665.     COUNT                           \ Get text start and length
  1666.  
  1667.     GFXTEXT                         \ Output text
  1668.  
  1669.  
  1670.     20 10 CURPUT                         \ Place cursor
  1671.  
  1672.     ." Hello....Press <SPACE> to exit!"  \ Some console text output
  1673.  
  1674.  
  1675.     BEGIN                    \ Start a BEGIN/UNTIL construct 
  1676.  
  1677.       KEY                    \ Wait for a keypress  
  1678.  
  1679.       32                     \ ASCII code for <SPACE> is 32
  1680.  
  1681.       =                      \ See if KEY value = 32
  1682.  
  1683.     UNTIL                    \ Loop until result is TRUE
  1684.  
  1685.   THEN
  1686.  
  1687.   CLOSESYSTEM                \ Close environment
  1688.   ;
  1689.  
  1690.   TUTORIALPROGRAM            \ Actually execute the new "program" word.
  1691.  
  1692.  \ End of program
  1693.  
  1694.  
  1695. *************************************************************************
  1696.  
  1697. -------------------------------
  1698. A few simple hints on debugging
  1699. -------------------------------
  1700.  
  1701. HeliOS has a very powerful user-configurable debugger, but for most
  1702. debugging you should never need to use it!  The following hints should
  1703. be taken as general programming guidelines, and for detailed discussion
  1704. of the HeliOS debugger you should refer to the debugger documentation.
  1705.  
  1706. There are a few simple techniques which, combined with sensible programming
  1707. strategies (for example, do not write 200k of source code altogether with
  1708. no testing then expect it to work instantly...), will enable you to debug
  1709. code very simply.
  1710.  
  1711. When a bug occurs the program will often (probably!) crash.
  1712.  
  1713. The best simple debugging technique is to put a repetitive debug line
  1714. into the code up to and including the crash point.
  1715.  
  1716. This line should display the stack status and wait for the space bar
  1717. to be pressed.  Something like the following will do nicely:
  1718.  
  1719.  ." Now at line xxx. Stack reads: " .S ." <SPACE> to continue" WAITSPACE CR
  1720.  
  1721.  
  1722. A few of these lines included in your code will give you a sequential
  1723. talk-through until the crash point is reached.
  1724.  
  1725. Start with the high level code first and then work into your subroutines:
  1726. in this way you can home in on the actual fault.  It is good practice to
  1727. check each subroutine thoroughly as it is completed, but nevertheless the
  1728. most unexpected results can occur when even apparantly sound subroutines
  1729. are used together in complex ways.
  1730.  
  1731. The stack status message debug line suggested above will probably mess up
  1732. your program's screen display, but that does not really matter in a debug
  1733. operation.
  1734.  
  1735. Always check for stack aberrations first. Be aware of what the stack should
  1736. be reading and check your debug stack readouts scrupulously.
  1737.  
  1738. If you like, include DUMP commands in your debug instructions to dump areas
  1739. of memory for careful scrutiny.
  1740.  
  1741. There are so many ways for code to fail it is impossible to cover all the
  1742. aspects of debugging. Also debugging is a very intuitive thing and everyone
  1743. has very personal preferences.
  1744.  
  1745. The main thing is to never assume ANYTHING to be OK without double checking,
  1746. and be prepared to be patient and check EVERYTHING relating to your problem
  1747. with an open mind.
  1748.  
  1749. Check your stack dumps minutely, dump and also check any areas of memory
  1750. you think may be suspect, check variable values by including them in your
  1751. debug lines where appropriate.
  1752.  
  1753. One big source of trouble is using address pointers which should really be
  1754. pointing at something useful like a screen structure address, but actually
  1755. contain zero.  For example, in our little program above, we checked that
  1756. the screen had opened OK and that its returned value was not null. If we
  1757. did not do this and then went on to use the screen handle, not realising
  1758. that it was zero, terrible things would happen.....
  1759.  
  1760. This sort of mistake is quite easy to make in more complex code, and can
  1761. be very nasty.  A golden rule on a multitasking machine like the Amiga
  1762. is never to assume that an allocation or opening routine must always
  1763. succeed.  Always check to see if everything has opened correctly, and
  1764. always take care to initialise all fields of data structures correctly.
  1765.  
  1766. *************************************************************************
  1767.  
  1768. -------------------
  1769. Additional reading?
  1770. -------------------
  1771.  
  1772. Perhaps you are wondering whether HeliOS is similar to any other languages
  1773. and whether you can get any books to help you learn to program?  
  1774.  
  1775. It is always useful to read a variety of documentary material when you are
  1776. learning a new programming language because different authors will often 
  1777. give you very different and valuable insights.
  1778.  
  1779. HeliOS is a threaded interpretive language derived from Forth, so many
  1780. of its simplest commands are Forth oriented.  A basic understanding of
  1781. Forth (which is a much smaller language in scope than HeliOS) will
  1782. certainly help you get started with HeliOS, and if you have access to
  1783. any Forth textbooks these will give you a good idea of the way HeliOS
  1784. programs are structured.
  1785.  
  1786. HeliOS uses a stack for much of its parameter passing, as well as using
  1787. reverse polish notation like Forth, so you will certainly benefit by
  1788. reading about these concepts in any of the excellent Forth texbooks
  1789. available.  Forth text books will provide you with many helpful insights
  1790. if you want to read them as background information: however, you should
  1791. beware of taking the analogy between Forth and HeliOS too far.  The fact
  1792. is that the similarity between the languages is superficial and sometimes
  1793. deceptive, so take care not to learn false ideas.
  1794.  
  1795. As a Forth instructional text we advise you to purchase Leo Brodie's
  1796. excellent text "Starting Forth", published by Prentice Hall in paperback.
  1797.  
  1798. You will certainly need to study specialised texts on the Amiga if you
  1799. want to get the best out of HeliOS because HeliOS, like "C", makes use of
  1800. the Amiga operating system and also allows direct Amiga hardware control.
  1801.  
  1802. The Addison-Wesley Amiga manuals are an excellent investment if you are
  1803. serious about Amiga programming, and Compute Books' "Mapping the Amiga"
  1804. is an extremely useful reference text.
  1805.  
  1806. HeliOS can supply an excellent comprehensive set of example programs on
  1807. all HeliOS commands written by Sebastien Veyrin-Forrer.  These short
  1808. example programs detail the use of every word in the HeliOS vocabulary.
  1809.  
  1810. ----------------------------------------------------------------------
  1811. End
  1812. ----------------------------------------------------------------------
  1813.