home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-18 | 70.4 KB | 1,813 lines |
-
- ------------------------------------------------
- An Introduction to Elementary HeliOS Programming
- ------------------------------------------------
-
- This introductory tutorial is intended to explain a few general ideas
- which may help you get started with HeliOS.
-
- Because simple once-only statements of fact are not the best way of
- introducing a complex subject, we have provided tutorials which cover
- similar ground in different ways.
-
- Some of the ideas in this tutorial will be different expressions of
- ideas related in other tutorials, and some of the material will be new.
-
- Hopefully this many-faceted approach will help make some of the more
- unfamiliar concepts accessible to most people, and once you are confident
- enough to write your own first programs you will be able to pick up
- further knowledge directly from the reference material as you need it.
-
- So don't just say "Oh..we've already read this!" and gloss over things,
- unless you already are very confident of your understanding, because
- there may be some new ideas in here.....
-
- ---------------------------
- Getting started with HeliOS
- ---------------------------
-
- HeliOS is a Forth-like language, especially in its simpler aspects, and
- the more sophisticated features of HeliOS build upon a central core of
- functions which are closely related to fig-Forth.
-
- This tutorial will discuss a few simple concepts which relate to Forth
- and Amiga programming in general without delving into deeper aspects
- of HeliOS. This is not a detailed HeliOS language lesson, and does not
- deal in depth with programming the Amiga operating system and hardware.
-
- It will not take long before you are able to write your own first HeliOS
- program. If you follow the introductory instructions and get the small
- demonstration programs working you will soon be all ready to start writing
- real working programs which include text and graphics.
-
- To help you get started with your own programs we include a standard
- "start up and close down" mini-program which you can use as a general
- basis for all your early experimental code. This "framework" program
- will enable you to open screens and windows, get user input, print text
- and display graphics: all the elements of simple programming in fact.
-
- We also include several source code files which introduce slightly more
- advanced techniques while still being quite accessible to beginners. It
- is easy to modify these programs to make your own simple games and from
- there you can progress to studying the more complex examples provided,
- such as the full source code for the HeliOS "Defender" game.
-
- It may be a little boring, but even if you are not new to Forth-type
- lanuages please read through the introductory tutorials BEFORE trying
- to actually change any of the example programs provided. This will help
- prevent initial frustration, because HeliOS is a very unusual language
- and a certain amount of insight into how HeliOS works is necessary even
- for experienced programmers.
-
- ------------------------------------------------------
- What do the terms "Compiling" and "Interpreting" mean?
- ------------------------------------------------------
-
- The text which contains the program instructions you wish to give to the
- computer is called "source" code, because it is the "starting" point for
- a translation process. This translation produces the actual "executable"
- code which is executed by the computer's CPU (central processing unit).
-
- The process of producing machine-readable CPU executable code from the
- human-readable source code is known as "compiling". Strictly speaking,
- "compiling" is the term used to desribe the process whereby the source
- code for a program is converted to executable code in the form of a file
- which can be "run" or "executed" later.
-
- Some computer languages, rather than compiling source code into executable
- code as a whole, translate and execute each bit of source code as they go.
- This process is called "interpreting". The latter languages run programs
- very slowly because of the inefficient on-the-fly interpretation process.
- They do, however, have the advantage that you can "try out" code at once
- to see how it works: an "interpretive" language gives an instant response.
-
- The pure "compiler" languages produce much faster final code, but in turn
- they suffer from a rather serious disadvantage in that the process of
- compilation is quite involved and time consuming. This means that the
- programmer's task of compiling, testing, rewriting, and recompiling can
- be a very slow and non-interactive (often frustrating) occupation.
-
- HeliOS is a "compiler", but it also has an "interpretive mode" as well,
- which is a good thing because it means that you can create fast compiled
- programs AND test them interactively as you go. This feature of HeliOS
- alone is a very good reason for using it as a "learning" language, and
- the efficiency with which it both "interprets" and "compiles" lifts it
- above any other language on the Amiga in this respect.
-
-
- ------------------------
- HeliOS Program Structure
- ------------------------
-
- The first thing to learn is the correct way to write your "source code",
- because any computer language can only understand code in a very specific
- text format. Fortunately there are very few "rules" to learn with HeliOS
- and there are no constraints such as "line numbers", or "strictly typed
- variables".
-
- Traditional Forth did employ a quite rigid and unusual form of source code
- stored in special "blocks", but HeliOS allows great freedom of text layout
- within the framework of a few simple but necessary rules.
-
- Some computer languages simply allow a whole program to be one single long
- "stream" of code, but this can be highly confusing. The more sophisticated
- languages allow code to be broken down into easy-to-handle sub-sections, or
- "subroutines", which can in turn be logically organised in a clear and
- functionally efficient manner. The latter type of language is called a
- "structured language".
-
- HeliOS programs are highly structured, and the language uses a collection
- of subroutines, often called "Words", which are created using a source code
- construct called the "colon definition". This name is used because each
- new subroutine definition starts with the colon ":" character.
-
- Within the "colon definitions" which define your functional code, there may
- be used all the usual logical constructs such as "IF-ELSE-THEN", "DO-LOOP",
- "BEGIN-UNTIL" etc etc. All these constructs are easy to use and allow you
- to create neat and easy to read logically structured code.
-
- In effect HeliOS programming consists in defining new words which extend the
- language itself, and as such is a very flexible and intuitive process. You
- can lay out programs in a very free way, and you may use any text editor
- which produces standard ASCII files, although it well generally be most
- convenient to use the integrated HeliOS editors because you can compile
- code directly from there.
-
- -------------------
- "Colon Definitions"
- -------------------
-
- The colon definition allows you to define an action and give a name to the
- resulting functional unit. The new "subroutine", or "Word", can then
- be used by simply entering its name in later source code. You have actually
- created a new operator which is just as much a part of the language as the
- initial HeliOS Core vocabulary functions.
-
- The start of a new subroutine is designated by a colon, and, after the code
- specifying what the new word does, we end the definition with a semicolon.
-
- Look at the example below:
-
- : NEWWORD |<--------definition-------->| ;
-
- Here you can see the colon and the semicolon with the definition placed in
- between. Note that immediately following the colon is the word NEWWORD,
- and, as you may have guessed, this is the name of our new subroutine.
-
- Remember that YOU choose the name of the new function: it can be anything
- you like, but always try to use distinctive and descriptive terms to make
- your code more comprehensible to you. If you choose names carefully your
- code can be made almost as readable as English language. On the other hand
- it is very easy to write very incomprehensible code indeed......
-
- A lot of your HeliOS code will consist of the use of the colon definition,
- so you will soon become familiar with it. We will give plenty of examples
- later in the tutorial.
-
-
- ---------------------------------
- HeliOS "WORDS" and the dictionary
- ---------------------------------
-
- HeliOS subroutines are called "WORDS", the total set of words available is
- called the "VOCABULARY", and the place where all the words are stored in
- the computer's memory is called the "DICTIONARY".
-
- Because HeliOS source code is concerned with very "linguistically" oriented
- activities, and because the definition and use of language is a very vital
- part of HeliOS, the term "WORD" tends to become a rather overworked part of
- HelIOS terminology. This all stems from traditional Forth usage.
-
- Historically Forth programmers have always referred to subroutines and
- their definitions as 'WORDS', but this can be confusing because the term
- WORD was used in several different ways in Forth computing parlance -
-
- 1. It defines a quantity of memory - 2 bytes or 16 bits. ( see later )
-
- 2. It is used to refer to the basic functional units of the Forth
- Language in terms of WHAT THEY DO operationally.
-
- 3. It is used in the English Language sense to refer to the actual NAME
- of the subroutine - the actual letters which you type to define it.
-
- A little care has to be taken, when you are first starting with HeliOS, to
- understand the context in which the word "WORD" is used!
-
- All the commands and subroutines that HeliOS uses, including both your own
- subroutines and predefined HeliOS word definitions are stored in the HeliOS
- 'dictionary'.
-
- As each new definition is added, the free space in the HeliOS dictionary is
- reduced. This space has a fixed limit, and you can always see how much room
- is left in the dictionary by looking at the status display at the top of
- the HeliOS screen. When the dictionary is full you can write no more code,
- but since HeliOS compiled code is VERY compact this would mean that you had
- already written a very large program indeed.
-
- You can list the contents of the Dictionary simply by typing "VLIST" at the
- command line (described later), or using the menu options in the Interpreter
- "HeliOS" menu.
-
- It is important to understand how the dictionary works because the general
- compilation method used by HeliOS is quite unlike that of most other Amiga
- languages.
-
-
- Basically this is what happens -
-
- 1. You create a subroutine by typing in one or more lines of source code.
-
- 2. The executable code is then "compiled" and stored in the dictionary
- in a form which can be "understood" by the computer.
-
- 3. The name you gave the new "word" is stored SEPARATELY in a special list
- rather like an index, which allows the word to be found and used later
- merely by entering its name.
-
-
- ( SPECIAL NOTE about 3. above:
-
- HeliOS is very different from traditional Forth in the way that it
- stores word names in a separate list. If you are a seasoned Forth
- programmer, or have a book on traditional Forth, you should read and
- remember the following note, as it will beneficially effect your whole
- programming style.
-
- When a HeliOS program is finally run the list of word names is no
- longer needed. This means that when you produce completed stand-
- alone programs the list of names can be omitted. If you think about
- it you will see that this is very useful, because it means that you
- can use long descriptive names for your subroutines without having
- to worry about them cluttering up your program later.
-
- This may seem very obvious, but traditional Forth actually stored the
- word names permanently within the program code and you may find books
- which advise you to use short names for this reason. Using HeliOS
- you can relax and use word names as long as you like - just try to
- make your names useful and descriptive. )
-
-
- Every time these three steps are performed the compiled code is added to
- the dictionary. If you recompile a subroutine and do not change its name,
- the earlier version(s), although still stored in the dictionary, will be
- left in place but superceded by the latest addition. This means that your
- latest definition will always be the one used in response to typing the
- subroutine name, but the "old" definitions will still be there hidden in
- the dictionary.
-
- During a typical session you may well work on a program by continually
- recompiling and testing code. If you make no attempt to clear previous
- additions to the dictionary then it will be filled quite quickly.
-
- The dictionary can be totally cleared back to the fixed CORE dictionary
- ( the set of standard words which are available at startup ) by using the
- expression:
-
- FORGET **CORE**
-
- Placing this at the start of a program source code file ensures that you
- can keep recompiling the source code without subroutine definitions being
- duplicated and without the dictionary gradually being filled up.
-
- We will from now on call the basic set of HeliOS commands, which is ALWAYS
- available, the CORE dictionary (or vocabulary), and all the subroutines
- defined in your own code as the USER dictionary (or vocabulary).
-
- Here are three command words to list the vocabularies:
-
- CVLIST -> List the CORE vocabulary
- UVLIST -> List the USER vocabulary
- VLIST -> List the CORE vocabulary followed by the USER vocabulary
-
- ------------------------------------
- Computer Memory and the HeliOS Stack
- ------------------------------------
-
- Memory is the basic storage medium for program code and data.
-
- Memory can be thought of as a series of cells, each of which can hold a
- numerical value, and the way in which each value is interpreted is largely
- determined by the code within your program.
-
- HeliOS uses a special device called a STACK, which is actually just a small
- organised subsection of the large general memory pool. Rather than being
- randomly accessed in any order, the stack is accessed sequentially like a
- pile of plates, or a deck of cards.
-
- Data is, in general, placed on the top of the stack and then removed when
- it is needed later.
-
- As more and more items are stored on the stack it grows in size, and the
- oldest items, those placed on the stack first, are left at the bottom.
-
- The HeliOS stack is employed to store sets of numbers which are going to be
- used almost at once by other subroutines, and can be regarded as a quick
- temporary store. It can also be looked upon as a "channel" of information
- between sequential operations. Typically one operation will put a number
- onto the stack, and the next will take the number off the stack and use it.
- You can think of it almost as a type of "messenger" carrying data between
- different parts of your program: a kind of "dumb waiter".
-
- Many HeliOS words, including your own program subroutines, look for and
- return values on the stack, and this process is called "parameter passing".
-
- In the past many would-be Forth programmers were initially terrified of
- using the stack because they had never used such a thing and had perhaps
- used other languages which employed NAMED VARIABLES rather than a stack.
- Actually you will soon see that the stack is ridiculously easy to use and
- gives you a lot more programming power than the restrictive use of variables
- for all parameter passing. In HeliOS you can use the stack or you can use
- named variables, or both together: so you have more power and more choice.
-
- HeliOS provides a large number of words for manipulating the stack,
- and these should be learned as soon as possible - they will soon become
- familiar since they are in constant use in ALL your HeliOS code. This is
- because you are constantly needing to adjust the position of data items
- on the stack, as well as adding, deleting, and duplicating items.
-
- Traditional Forth had just a few stack control words, and managed any more
- complex operations needed by combining many of these simple words together.
- Because the names used in Forth for stack operators are short and cryptic,
- complicated combinations of them are very unreadable. Not only this, but
- use of a lot of generalised words to do a job rather than one specific word
- is very inefficient. This was THE major problem with early Forth systems.
-
- This problem of "stack control" is one of the weakest parts of traditional
- Forth, and is largely responsible for Forth code getting a reputation for
- being very unreadable. This is a shame, because Forth was potentially the
- most "readable" of all computer languages, and it was only the limited
- vocabulary of early Forth systems which caused the difficulty.
-
- HeliOS has removed the necessity for worry over stack manipulation
- by providing the most complete set of specialised words ever available
- in a Forth-type language. Try to gradually incorporate more and more of
- these words into your knowledge of HeliOS, so that you can use just the
- right specific word for the job rather than a series of less appropriate
- ones.
-
- HeliOS has adopted another totally new philosophy which departs from Forth
- tradition: all the stack control words in HeliOS are machine coded for
- maximum speed and efficiency.
-
- We have dwelt perhaps overmuch on the stack, because the use of the stack
- will be really important throughout all of your HeliOS programming. The
- concept of always using the minimum of stack control words throughout
- your code is VERY important if your programs are to be readable, easily
- maintained, and fast in operation.
-
- Before leaving this important subject, here is a very quick practical
- example of stack manipulation so that you can see what it is all about.
-
- Take a stack with four numbers on it: 1, 2, 3, 4
-
- Imagine that the "4" is at the top, and the "1" is at the bottom.
-
- Suppose that we want to duplicate the third number from the top and
- place a copy of it on the top of the stack. ( Believe it or not, this
- sort of thing is quite commonly required! )
-
- So we need to operate on our initial stack to get: 1, 2, 3, 4, 2
-
- Let us assume that we have four stack operators:
-
- DUP - this duplicates the number on top of the stack
- eg. 1, 2, 3, 4 -> 1, 2, 3, 4, 4
-
- SWAP - this exchanges the top two stack items
- eg. 1, 2, 3, 4 -> 1, 2, 4, 3
-
- DSWAP - this exchanges the top two "double" stack items
- eg. 1, 2, 3, 4 -> 3, 4, 1, 2
-
- ROT - this REMOVES the third number on the stack and
- puts it onto the top
- eg. 1, 2, 3, 4 -> 1, 3, 4, 2
-
- How do we solve our simple problem?
-
- Why not try it as an exercise on paper?
-
- We could do the following: 1, 2, 3, 4
-
- ROT ->
- 1, 3, 4, 2
-
- DUP ->
- 1, 3, 4, 2, 2
-
- ROT ->
- 1, 3, 2, 2, 4
-
- DSWAP ->
- 1, 2, 4, 3, 2
-
- ROT ->
- 1, 2, 3, 2, 4
-
- SWAP ->
- 1, 2, 3, 4, 2
-
- Success! We did it! This way is slow, but it DOES work.
-
- ( Actually it can be done quicker than this - did you manage it? )
-
-
- But look......we have the following series of operators:
-
- "ROT DUP ROT DSWAP ROT SWAP"
-
- This is horrible to read, and even worse to debug when combined with a lot
- of other similar sequences. It is also very time consuming to compile and
- execute, since it takes SIX words to do one simple job. If we could do
- this operation in ONE word we should have SIX times better code - it is
- as simple as that.
-
- HeliOS would do the following in one word - and it would be a very fast
- internally machine coded word too.
-
- HeliOS would say: 1, 2, 3, 4
-
- 3PICK ->
-
- 1, 2, 3, 4, 2
-
-
- So we have used the special operator "3PICK" = "pick out the third item"
-
- We have written a program which compiles AND runs SIX times faster than
- the first method.
-
- This kind of thing is fundamental to good HeliOS programming, and you will
- constantly come up against coding tasks exactly like the above example.
-
-
- ------------------------
- The HeliOS stack display
- ------------------------
-
- To help you get accustomed to the working of the stack, HeliOS has a
- permanent stack display at the top of the Interpreter window.
-
- Try doing a few calculations and manipulations like the examples above
- and watch the stack display. This will soon give you a feeling for how
- the HeliOS stack works, because seeing the numbers change in the set of
- cells displayed graphically on screen is an excellent aid in visualising
- stack operations.
-
-
- ----------------------------------------------------------------
- Passing Parameters between HeliOS Words and using Stack Diagrams
- ----------------------------------------------------------------
-
- Let us take, as a simple example, the HeliOS Word "FPENSET". This
- word sets the foreground text pen colour, which is simply a number. On
- a four colour screen the text could be displayed in colour 0, 1, 2 or 3.
-
- Let us assume we are starting from an empty stack.
-
- Our word FPENSET needs to know what colour we want it to use, and this is
- done very simply in HeliOS by passing the colour number as follows:
-
- 1 FPENSET for "colour 1"
-
- or 3 FPENSET for "colour 3"
-
-
-
- Here the "parameter", the colour number, is "1" (or "3"), and is written
- in your source code as a simple number preceding the word FPENSET.
-
- This looks very natural and simple, and indeed this simplicity is a very
- good feature of HeliOS, but a little more is happening than is apparent.
-
- What actually happens is that the number "1" is stored on the stack until
- it is used by FPENSET, which leaves the stack empty. This situation is
- represented by the "stack diagram", which you will see used throughout
- the HeliOS Dictionary definitions. This is a means of representing what
- happens to the stack during the operation of a HeliOS Word.
-
- In the case cited above we have a stack diagram as follows:
-
-
- n - - -
-
-
- The "n" represents the colour number which the word FPENSET expects to
- find placed on the stack. The three "-" signs signify the computing
- process as FPENSET does its work, and the fact that there is no number
- afterwords means that FPENSET actually uses internally and removes its
- single parameter, leaving nothing on the stack itself.
-
- The parameter to be passed to the subroutine is stored temporarily on
- the stack, the subroutine then removes it and, in this case, returns
- with the stack clear.
-
- This method is crucial to HeliOS operation. Several parameters can be
- passed to subroutines via the stack, as you will see in the examples
- given below. The word GFXRECTFILL, for example, uses four parameters
- denoting the corners of a box to draw a filled rectangle.
-
- Many subroutines use the stack to return parameters, and your program
- must constantly keep track of the stack to ensure that this process of
- passing parameters is kept in order.
-
- The HeliOS words used to make ordinary arithmetic calculations all get
- their parameters from the stack, operate on them, and then return the
- result of the calculation on the stack.
-
- In a simple addition two parameters are needed, and the result, which
- is a single parameter, is returned on the stack -
-
- 3 5 + add two numbers 3 and 5, leaving the result on the stack
-
- . display on screen the value on the stack ( the "result" )
-
- The stack diagrams of these two words would be:
-
- "+" n1 n2 - - - n3
-
- "." n3 - - -
-
-
- ---------------
- Using Variables
- ---------------
-
- While HeliOS uses the stack for most of its short term parameter passing
- operations, ordinary memory can be used for data storage on a more long
- term basis. Languages like BASIC and PASCAL use named variables to access
- the memory in which the data is stored without involving the programmer
- with the actual "physical" memory address, or indeed with "stacks".
-
- HeliOS can do the same thing if required, and while the stack is much more
- efficient for most parameter passing (and gives HeliOS a significant speed
- advantage), there are many occasions where it is best to use variables.
-
- A variable can be created using the word VARIABLE and data can be moved in
- and out using the two HeliOS words "!" (which is pronounced "store") and @
- (which is pronounced "fetch").
-
- When a variable is created in HeliOS it always has to be initialised, but
- if no particular initial value is needed you can always set the initial
- value to zero.
-
- A variable created in this way is stored in the dictionary.
-
- For example,
-
- 0 VARIABLE MILES
-
- will create a VARIABLE called "MILES" initialised to zero.
-
- In a similar manner,
-
- 50 VARIABLE MILES
-
- will create a VARIABLE called "MILES" and initialise it to 50.
-
-
- We can now get and display the memory contents referenced by the word
- "MILES" as follows:
-
- MILES @ .
-
- (or a shorter version: "MILES ?" which does exactly the same thing.)
-
-
- What is actually happening here?
-
- MILES \ Puts the address of the variable on the stack,
- \ or, more accurately, the address of the memory
- \ cell where the the value 50 is stored
-
- @ \ Gets the data stored at that memory address and
- \ puts it on the stack, having first removed the
- \ address from the stack
-
- . \ Displays and removes the "top of stack" value
-
- We have not specifically accessed memory numerically - we have just asked
- for the contents of the VARIABLE defined by the name "MILES".
-
- This use of easy to remember words rather than numbers is a great help in
- writing easily understood code.
-
-
- In a similar manner we can store a value in a variable using "!" ("store")
-
- 12 MILES !
-
- will store the value 12 in the memory location defined by the word MILES.
-
-
- ---------------------------------------------
- A little note on 16-Bit and 32-Bit Addressing
- ---------------------------------------------
-
- A computer deals with binary numbers, which are actually just like simple
- two-state "on or off" switches. These are each said to contain one "bit"
- of information, and can only represent the numbers 1 and 0.
-
- A single cell of memory contains an 8-bit number, which is a collection of
- 8 bits, and is called a "byte". This can represent a decimal number of up
- to "255", which is still a rather small unit of information.
-
- Because a byte is such a small "chunk" of information, we often use a much
- larger unit of 16-bits, 2-bytes, which we call a "word".
-
- Above this we have 32-bit numbers which are 2 "words" or 4 bytes in length,
- and these are often referred to as "long" or "longwords".
-
- So....the data which we store is usually in the form of 1, 2, or 4 byte
- numbers.
-
-
- Computers use similar numbers to define positions in memory, often called
- memory "addresses", so that they know where to store and fetch information.
-
- On a machine like the Amiga, memory is "addressed" by 32-bit, or 4-byte
- "long" numbers.
-
- HeliOS uses a little "trick" to avoid the use of these very large numbers
- all the time. It defines addresses within the HeliOS dictionary as 16-bit
- numbers and "internally" adds a further number to these addresses to get
- the true 32-bit address. So HeliOS can use 16-bit addressing or 32-bit
- addressing depending on whether an address is in dictionary memory space.
-
- Don't worry too much about these things for now; we simply mention them
- here to enable the code example later to be more fully comprehended. We
- will give a couple of examples here to clarify how HeliOS defines different
- length numbers and addresses, but do not attempt to learn this now, and do
- not worry if you cannot follow all the explanation.
-
-
- ------------------------------------------------------------------
- The HeliOS Dictionary is a 16-bit addressed, 16-bit data structure
- ------------------------------------------------------------------
-
- What does this "imposing" statement mean?
-
- To keep things simple for now we should just point out that HeliOS uses
- 16-bit numbers for its standard mode of operation. Numbers on the stack
- are stored as 16-bit "cells", and 32-bit numbers are stored as two of
- these standard cells. HeliOS stores 8-bit numbers on the stack again in
- a 16-bit cell, but ignores the top byte of the number.
-
- A 16-bit number is often referred to in HeliOS as a "single number".
-
- A 32-bit number is often referred to in HeliOS as a "double number".
-
- As well as using 16-bit data items as "standard", all memory addressing
- within the HeliOS dictionary memory space is usually specified by 16-bit
- numbers also (although any 16-bit HeliOS address can also be specified as
- a 32-bit address if required).
-
- In general then, HeliOS, like traditional Forth, is largely concerned in
- its internal operations with 16-bit numbers.
-
- Double word 32-bit addressing specifies a memory location directly as one
- large number. As its name implies, 4 bytes of storage are needed to handle
- this number. This 32-bit addressing is always used in conjunction with
- Amiga library calls, and cannot be avoided. A 32-bit address is stored
- on the HeliOS stack as two 16-bit numbers, but there are many HeliOS commands
- which treat this easily as one 32-bit entity.
-
- A 32-bit address is often referred to as a "long" address, or a "longword"
- address.
-
- 16-bit addressing is ONLY used to specify memory addresses within the main
- HeliOS dictionary. Remember always that this addressing technique specifies
- a memory location as an offset from a point of reference which is the start
- of the HeliOS dictionary.
-
- Here are two HeliOS command words which translate between 16-bit and 32-bit
- addressing for any addresses within the HeliOS dictionary:
-
- W>L ( a1 - - - l1 ) -> Converts a 16-bit address to a 32-bit address
-
- L>W ( l1 - - - a1 ) -> Converts a 32-bit address to a 16-bit address
-
- --------------------------------------------------------------
- How HeliOS specifies 16-bit and 32-bit addressing and numbers.
- --------------------------------------------------------------
-
- Addressing can be very confusing and people often get mixed up with 16
- and 32 bit data values and 16 and 32 bit addresses. To avoid confusion
- when using these differing quantities we need to use a regular notation.
-
- HeliOS uses a standard notation of:
-
- a "D" prefix for double length data
-
- an "L" suffix for long addressing
-
-
- An example using VARIABLES may help clarify the matter:
-
-
- Both 16-bit and 32-bit data storage variables can be created as follows:
-
-
- 50 VARIABLE MILES
-
- Creates a 16-bit variable called 'MILES' and initialises
- it to 50.
-
- This variable is referenced by a 16-bit address.
- Use of the word 'MILES' puts a 16 bit address on the
- stack, indicating the memory location where the number
- 50 is stored as a 16-bit number in the HeliOS dictionary
- memory space.
-
-
- 50. DVARIABLE MILES
-
- Creates a 32-bit variable called 'MILES'. The full stop
- after the "50" indicates that this is a 32-bit number.
-
- In this case the 32-bit data value is stored at a 16-bit
- address, and use of the word "MILES" returns this 16-bit
- address where the 32-bit number "50." is stored.
-
- Note that the number 50 itself could be stored in an
- 8-bit space: the data size refers to the storage space
- and not the size of the actual number stored there.
-
- The D prefix signifies a double length data variable -
- remember this, as it is the standard form of notation.
-
-
- 50 VARIABLEL MILES
-
- Creates a 16-bit variable called 'MILES' stored at a
- 32-bit or Long address. Use of the variable 'MILES'
- returns a 32-bit number on the stack representing the
- longword address where the 16-bit value is stored.
-
- The L suffix signifies a long address, and again this is
- a standard notation for "long" 32-bit addressing.
-
-
- 50. DVARIABLEL MILES
-
- Creates a 32-bit data variable stored at a 32-bit address.
-
- Note the 32-bit data indicated by the "." after the "50"
- and the "D" prefix to indicate a 32-bit data variable.
-
- Note again the use of the "L" suffix to indicate the long
- addressing mode.
-
-
- The above example illustrates standard HeliOS notation, which you should
- become familiar with as soon as possible.
-
- Remember that the D prefix always relates to double length data and the
- L suffix relates to long addresses.
-
- It is important to remember here that variables within the main HeliOS
- dictionary can actually be 16-bit addressed or 32-bit addressed. Those
- given 16-bit addresses can be converted to 32-bit addresses using the
- HeliOS Word "W>L" ("word-to-longword"). An address thus converted may be,
- in turn, restored to 16-bit form using the reverse operation "L>W".
-
- Data values can easily be converted from single to double size using the
- word "S>D" ("single-to-double"), but values can only be converted from
- double to single if they are less than 16-bit in "numerical" size.
-
- Unsigned single numbers can be converted to double numbers by simply adding
- a zero to the stack, since this zero represents the high word of the new
- 32-bit value.
-
- It is important to handle parameter passing (via the stack) correctly if
- your programs are to run satisfactorily, so you have to be careful to use
- 16 and 32-bit values and addresses properly. If a subroutine expects a
- double word parameter (4 bytes) passed on the stack, the computer will
- probably crash if you only pass a single word parameter of 2 bytes!
-
-
- ---------------------------------------
- Using "Text Strings" in HeliOS programs
- ---------------------------------------
-
- The term "String" is used in relation to text storage in memory. Since
- computers only deal with numbers we have to represent text as a "string"
- of numeric codes in memory.
-
- Each text character is defined by a numeric code called an "ASCII" value,
- which is a standard code used for representing letters as numbers in the
- computer's memory.
-
- A series of continuous bytes in memory which represent text ("ASCII")
- characters make up a text "string".
-
- Strings are handled either as "counted strings", which are always stored
- along with a number indicating their length, or "null terminated strings"
- which simply carry on in memory until a "0" character is encountered.
-
- In both cases a memory address is used to specify the first byte of the
- string, and this number is used to manipulate the string. As with numeric
- data a string "address pointer" can be a simple number on the stack, or
- may be "named" like a variable.
-
- The first byte of a counted string is always called the "count byte" and
- is a number representing the total number of text characters in the string.
-
- In the case of the "null terminated" string the first byte of the string
- is simply the first character of the string itself, which continues on in
- memory until a null value "0" occurs: hence its name.
-
- Counted strings have limited length, since the single "count" byte has a
- maximum value of 255. Null terminated strings, on the other hand, can be
- of any length.
-
- Traditionally Forth used counted strings, but the Amiga operating system
- uses null terminated strings. HeliOS has comprehensive support for
- both types, as well as easy conversion from one to the other.
-
- HeliOS has an extra useful feature in that counted strings all have
- a null terminator as well. To access a counted string as "null terminated"
- all you have to do is increment the address of the string by one, thus
- moving forward past the initial "count" byte to the first character.
-
- HeliOS has a large number of string handling routines, many of which
- handle either 16-bit or 32-bit addressing. As a general rule, handle all
- strings as 16-bit addressed in simple programs unless you need to pass the
- string to an Amiga library function. In this case you can easily convert
- to a 32-bit address using "W>L" as required.
-
- --------------------------------------------------------------
- A very simple and useful HeliOS string handling word - "LIT$".
- --------------------------------------------------------------
-
- Using LIT$ within Colon definitions
-
- LIT$ is used within a colon definition to allow compilation of a counted
- string within your program code. The text string must be enclosed between
- two dollar ("$") characters, as this example shows:
-
- : PRESSMESSAGE LIT$ $Press SPACE-BAR To Continue$ ;
-
- This example creates a new word PRESSMESSAGE, which employs "LIT$" to store
- the text between the two dollar characters ("Press SPACE-BAR To continue")
- within the dictionary. When you later use the word PRESSMESSAGE the 16-bit
- address of the string is returned on the stack. It can then, for example,
- be printed out to the screen using the word "$." in another word as follows:
-
- : SHOWPRESMESSAGE PRESSMESSAGE $. ;
-
- You will find this little word "LIT$" VERY useful indeed. We use it in
- the example program below, and you should learn to use it yourself in your
- own programs as soon as possible.
-
-
- -------------------------------------
- General INPUT and OUTPUT using HeliOS
- -------------------------------------
-
- Obtaining User Input
-
- HeliOS has a general purpose input word "KEY". This word causes a program
- to wait for an input event to occur. Input events include keyboard entry,
- mouse button depression, mouse movement, gadget selection, menu selection
- or ticker activation. We use the word "KEY" because traditional Forth used
- this word, although it only accessed keyboard events, unlike the more
- extended HeliOS version which handles ALL events.
-
- The user input word "KEY" will report input events from whatever active
- window YOU specify. You can designate ANY window as the current input
- window using the HeliOS special word "MAKEINWINDOW". This is an
- immensely powerful and important word, as it includes within itself a
- whole "sub-program" which in any other Amiga language you would have to
- write for yourself. This "sub-program" sets up a special task to monitor
- and translate all input events, and has many very sophisticated features
- unique to HeliOS. All this power translates, from your point of view, to
- a very easy use of the single word "KEY" - all the hard work is done for
- you!
-
-
- -------------------------------------------------
- Sending Output to the User via the screen display
- -------------------------------------------------
-
- There are two basic types of screen text output - console output and graphic
- text output.
-
- Text characters are usually written to console windows in streams, which
- have full scrolling, cursor movement, and text formatting facilities etc.
-
- In general all dynamic, changing text output is handled by "console" type
- displays.
-
- Graphic text output does not have these "text control" features and all
- text is placed on the screen as a static graphic "drawing". This means
- that, for example, text can only be deleted by overwriting the screen area
- occupied by the graphic image of the text.
-
- In general graphic text output is used for "painting" a graphic display with
- static text.
-
- Both kinds of text are fully supported by HeliOS, but the following
- simple examples use "console" text output for simplicity. Note that this
- console output is not always simple on the Amiga, and in other languages
- quite a lot of programming is required to set up any console output.
- HeliOS is unique in the power of its automated functions, and, as you will
- see, console text output has been made very powerful and easy.
-
- As a matter of interest, HeliOS has two powerful sub-programs which
- fully automate the setting up of all console text output and graphical
- operations within ANY designated window on ANY screen.
-
- Quite large programs would have to be written by YOU in any other language
- to achieve this functionality of HeliOS, which requires you to use just ONE
- word to set up each sub-program:
-
- "MAKOUTWINDOW" - sets up a VERY sophisticated console handling system
- with TEN automated text "streams".
-
- "MAKEGFXWINDOW" - sets up an automated graphics library handling system
- with single word operators for most graphic functions.
-
- Our final example program below will show you how to use these functions.
-
-
- -------------------------------------
- A FIRST TUTORIAL PROGRAMMING EXERCISE
- -------------------------------------
-
- Our tutorial program will start with a line of code which clears all words
- from the user dictionary, leaving just the CORE vocabulary -
-
-
- FORGET **CORE** \ Get rid of any old USER defined words
-
-
- The "\" character denotes an "end of line comment", and anything following
- this is ignored by the compiler. Always add plenty of descriptive comments
- to your code in this way, so that you know what is going on.
-
- Note here that ALL words in HeliOS source code should have a space before
- and after them. This is absolutely vital, and note that a space is also
- needed both before and after the "\" character, because this is also a
- HeliOS Word.
-
- To summarise these points, the above line of code has:
-
- At least one space
-
- The word "FORGET"
-
- At least one space
-
- The word "**CORE**" telling FORGET to clear all words back to CORE
-
- At least one space
-
- The word "\" which tells us that the rest of the line is a comment
-
- At least one space
-
- The words "Get rid of any old USER defined words" - the comment
-
-
- Now we will add a "colon definition" to our program.
-
-
-
- FORGET **CORE** \ Get rid of any old USER defined words
-
- : SAYHELLO ." HELLO WORLD" ; \ Make a word called SAYHELLO
-
-
- The colon definition above will create a new subroutine called SAYHELLO.
-
- Let us look at it's structure. It has -
-
- At least one space
-
- A ":" to start the definition
-
- At least one space
-
- A descriptive label, "SAYHELLO"
-
- At least one space
-
- The definition " ." HELLO WORLD" "
-
- At least one space
-
- A ";" to finish the definition
-
- At least one space
-
- A "\" which tells us that the rest of the line is a comment
-
- At least one space
-
- The words "Make a word called SAYHELLO" - the comment itself
-
-
- We now have a small program:
-
-
- FORGET **CORE** \ Dispose of any old USER defined words
-
- : SAYHELLO ." HELLO WORLD" ; \ Make a subroutine called SAYHELLO
-
-
-
- The next thing of interest is the definition ." HELLO WORLD".
-
-
- This can be split into three parts as follows.
-
- <SPACE> ." <SPACE> HELLO WORLD "
-
- The first part is the HeliOS word ." which tells the HeliOS system to output
- to the screen the words following it up to the next " character.
-
- The second part is the expression HELLO WORLD, which is the message we want
- to display.
-
- The third part is the quote character " which tells the HeliOS system that
- our enclosed quotation has ended. The double quote " is not a HeliOS WORD
- and does not need a space before it. It is called a delimiter and merely
- acts to delimit the end of an enclosed text message "string".
-
- To use the new word (subroutine) all we need to do is either type it at
- the command line after compiling our program, or include it in our program
- code after the definition.
-
-
- --------------------------------------
- Entering and compiling our new program
- --------------------------------------
-
- There are two ways of entering code. We can either use an editor or we can
- type in code at the the command line. The editor option is perhaps better
- in most cases because code can be saved to and loaded from disk files.
-
- The command line has a circular "history" buffer and is useful for testing
- small fragments of code which are being continually modified. It is very
- quick for small code testing jobs, but cannot be saved to disk.
-
-
- We will use an editor in this tutorial example, as follows:
-
- 1. Load HeliOS: the interactive screen appears at once.
-
- 2. Click the "Ed 1" button at the top of the screen to enter "Editor 1".
-
- 3. Now type in the following code -
-
- ( N.B.
-
- This text was intended to be used from a printed page.
-
- If you are using this text in the form of a disk file, you may already
- be viewing it in one of the HeliOS editors.
-
- In this case you can simply run the sections of code directly without
- having to type them in. )
-
-
- FORGET **CORE** \ Dispose of any USER defined words
-
- : SAYHELLO ." HELLO WORLD" ; \ Make a word called SAYHELLO
-
- SAYHELLO \ Use the new word we have created
-
- WAITSPACE \ Wait for the space bar to be pressed
-
- 4. Compile the section of code.
-
- This action will take you into the Interpreter and run the program.
-
- This is a program which actually does something. It will print to the
- screen the message "HELLO WORLD". Note that you can now type SAYHELLO
- at the command line and the message "HELLO WORLD" will appear on screen.
-
- Note also that you can use the up-arrow cursor key to bring back all the
- previously typed command lines and reuse them - this makes use of the
- circular command line "history" buffer mentioned above.
-
- The next thing to do, perhaps, is save the code to a disk file, so.......
-
-
- 5. Repeat step 2 to reenter the Editor, then select 'Save As' from
- the 'Load/Save' menu to access the HeliOS File Requester and
- save the file.
-
- Note that each time you resave a file with the same name as before
- HeliOS will create a backup file for you automatically.
-
- Having made a small working program we can now start to do some more
- interesting things with it.
-
- Listed below are a number of variations on our program for you to try.
-
- Use the editor again to modify the code already entered, then use the
- method outlined above to save and execute your code.
-
-
- Try each of the following variations:
-
- ( Note that you can omit the comments if you like )
-
-
- : SAYHELLO \ This version changes the output text position
-
- 10 10 CURPUT \ Set the text output position ("PUT" the "CURSOR")
-
- ." HELLO WORLD" \ Say hello
- ;
-
-
- : SAYHELLO \ This changes the output text position and colour
-
- 3 FPENSET \ Set the foreground pen - text colour
- 1 BPENSET \ Set the background pen - text background
- 10 10 CURPUT \ Set the text output position ("PUT" the "CURSOR")
-
- ." HELLO WORLD" \ Say hello
- ;
-
-
- : SAYHELLO \ This displays the message 4 times in line
-
- 4 0
- DO \ Loop 4 times
- ." HELLO WORLD" \ Say hello
- SPACE \ Put a space between messages
- LOOP
- ;
-
-
-
- : SAYHELLO \ To display the message 4 times on new lines
-
- 4 0
- DO \ Loop 4 times
- CR \ "Carriage Return" = Go to start of next line
- ." HELLO WORLD" \ Say hello
- LOOP
- ;
-
-
- Now for a more interesting one........
-
-
- : SAYHELLO \ This repeats the message 4 times on new lines in a box
-
- 3 FPENSET \ Set the foreground pen - text colour
- 1 BPENSET \ Set the background pen - text background
-
- 1 GFXSETAPEN \ Set the graphics drawing colour (box colour)
- 2 GFXSETOPEN \ Set the graphics outline pen colour (box outline)
-
- 1 GFXOUTLINE \ Switch on graphics OUTLINE mode
-
- 10 \ "x" pos, in pixels of the box's top left hand corner,
- \ measured from top left hand corner of screen
- 45 \ Top left "y" pos
- 150 \ Bottom right "x" pos
- 90 \ Bottom right "y" pos
- GFXRECTFILL \ Draw a filled rectangle (draw box)
-
- 0 GFXOUTLINE \ Switch off graphics OUTLINE mode
-
- 4 0
- DO \ Loop 4 times
- CR \ "Carriage Return" = Go to start of next line
- 4 CURFW \ Move the "CURSOR FORWARD" to give a margin
- ." HELLO WORLD" \ Say Hello
- LOOP
- ;
-
-
- And now an even more interesting one........
-
-
- : SAYHELLO \ This repeats the message 4 times on new lines in a box
-
- 3 FPENSET \ Set the foreground pen - text colour
- 1 BPENSET \ Set the background pen - text background
-
- 1 GFXSETAPEN \ Set the graphic drawing colour (box colour)
- 2 GFXSETOPEN \ Set the graphics outline pen colour (box outline)
- 1 GFXOUTLINE \ Switch on graphics OUTLINE mode
-
- 10 \ "x" pos, in pixels, the box's top left hand corner,
- \ measured from top left hand corner of screen
- 45 \ Top left "y" pos
- 150 \ Bottom right "x" pos
- 90 \ Bottom right "y" pos
- GFXRECTFILL \ Draw a filled rectangle (draw box)
-
- 0 GFXOUTLINE \ Switch off graphics OUTLINE mode
-
- 4 0
- DO \ Loop 4 times
- 4 \ Start at 4th position on line
- I 2 + \ Start at 2nd line + LOOP INDEX
- CURPUT \ PUT the CURSOR
- ." This is line" \ Print "This is line"
- I 1+ \ Increment the LOOP INDEX + 1 which is stored
- \ on the stack, (the index starts at 0)
- . \ Print the index number (stored on the stack)
- LOOP
- ;
-
-
- **************************************************************************
-
- ----------------------------------------
- Using Amiga Libraries from within HeliOS
- ----------------------------------------
-
- Amiga Libraries are special code modules which are provided to help you
- with various programming tasks, and are very simple to use. Libraries are
- either present within the Amiga ROM (Read Only Memory), or may be loaded
- from disk.
-
- The method of accessing a library is:
-
- 1. OPEN the library The Amiga loads and prepares it for use
-
- 2. CALL library routines You will need a reference book for definitions
-
- 4. CLOSE the library When you have finished with it
-
-
- Many Amiga library routines are included in HeliOS as part of the CORE
- dictionary. These functions are pre-written "interfaces" to specific Amiga
- library calls and do not require you to address the library directly.
-
- In addition, the main and most useful libraries are automatically opened for
- you when HeliOS starts up and closed when HeliOS closes down.
-
- These are the DOS, EXEC, GRAPHICS, LAYERS, and INTUITION libraries.
-
- If you do have to open a library yourself there is a simple to use HeliOS
- word called OPENLIB, which opens a library and returns the 32-bit library
- base address on the stack as follows:
-
- First, in our example we are going to open "diskfont.library", so we need a
- DVARIABLE to store the library base address when we have opened it.
-
- D0 DVARIABLE DFONTBASE \ Create a 32-bit variable DFONTBASE
-
- Now open the library.........
-
- LIT$ $diskfont.library$ \ Put counted library name string on stack
- 0 \ Put library revision number on stack
- OPENLIB \ OPEN the library
- DFONTBASE D! \ Store the library handle
-
-
- Having done this, always check to see that the new base variable is not
- still zero, in which case the library has failed to open for some reason
- and you need to sort out the problem.
-
-
- Closing a library:
-
- First remember that you only need to close libraries that you yourself
- have specifically opened. You do not need to close the standard libraries
- handled for you by HeliOS system.
-
- To close a library put the library base address on the stack and use the
- word CLOSELIB like this:
-
-
- DFONTBASE D@ CLOSELIB
-
-
- That's all there is to it...................easy!
-
-
-
- When a library is open and you want to use it, you need to know 3 things:
-
- 1. What is the library base offset for the routine you wish to call?
- This is found from Amiga documentation and will always be a negative
- number.
-
- 2. What "parameters" does that library call require before using it?
-
- 3. What results are returned after completion?
-
- These details are also found in Amiga library documentation.
-
-
- So assuming that you know all about the routine you are calling and its
- start-up parameters, you now need to know what to do with the start-up
- parameters when calling a library from HeliOS.
-
- HeliOS is very close to assembly language in operation, so it handles
- library calling parameters in a manner closely reflecting the way it is
- done in assembly language.
-
- If you look at the Amiga library documentation you will see that there are
- instructions for assembly language library calls, telling the programmer in
- which 680xx microprocessor registers to store parameters.
-
- You can gather from this that in assembly language you store parameters
- directly into the registers within the 680xx microprocessor before calling
- a library. The results of library calls are also stored in these 680xx
- registers when the library call has been completed.
-
- Don't worry if this sounds difficult - it is actually very easy!
-
- The 680xx has a set of 8 ADDRESS registers, labelled A0-A7, and a set of
- 8 DATA registers, labelled D0-D7. These registers are all 32-bit registers.
-
-
- Your library documentation will say things like
-
- Put Buffer Address into register A0
- Put Buffer Length into register D0
- Call Library
- Read result of call from register D0
-
-
- To translate this type of operation into HeliOS is very easy because
- you have a set of DUMMY REGISTERS in which to store your parameters and
- read your results.
-
- The DUMMY ADDRESS REGISTERS are accessed as double number 32-bit variables
- by putting the register number you require on the HeliOS stack and then
- using the word AREG to return the variable address.
-
- The same method applies to DUMMY DATA REGISTERS but this time you use the
- word DREG.
-
- When HeliOS calls a library for you, using the HeliOS Word LIBRARY,
- it simply unloads the dummy registers into the actual 680xx processor
- registers, calls the library, then unloads the 680xx registers back into
- the dummy registers. This is very useful because it means that the values
- in the dummy registers are retained for your use until the next time you
- make a library call.
-
-
- To carry out the example library call given above you would:
-
- Put Buffer Address into DUMMY register A0
- Put Buffer Length into DUMMY register D0
- Call Library
- Read result of call from DUMMY register D0
-
-
- To do this in Helios code you might write:
-
-
- BUFFERADDRESS D@ \ Get buffer address onto stack
- 0 AREG D! \ Store it in DUMMY ADDRESS REGISTER A0
-
- BUFFERLENGTH D@ \ Get buffer length onto stack
- 0 DREG D! \ Store it in DUMMY DATA REGISTER D0
-
- LIBRARYBASE \ Put address of Library base store onto stack
- -64 \ Get library offset onto stack
- LIBRARY \ Call library
-
- 0 DREG D@ \ Get result from DUMMY DATA REGISTER D0 onto stack
-
- Remember, the dummy registers will always directly reflect their 680xx
- counterparts before and after the library call.
-
- The word LIBRARY which makes the call is not at all complicated, you simply
- put the name of the variable where the library base address is stored onto
- the stack, followed by the library routine offset, then use the word
- LIBRARY exactly as shown above.
-
- Note that it is not the library base pointer itself that is used by the
- word "LIBRARY" but the 16-bit storage variable address.
-
- That is all there is to calling Amiga libraries, except for one thing which
- makes it even easier! In the above code we have accessed the result of the
- library call, in register D0, quite correctly using "0 DREG D@". Because
- this sequence is used very often we have included an easy and quicker single
- word alternative. Instead of typing "0 DREG D@" you can simply type the one
- word "D0RESULT" to get the value in DUMMY REGISTER D0.
-
-
- *****************************************************************************
-
- ----------------------------------------------------
- General procedures for Starting and Closing programs
- ----------------------------------------------------
-
- It is a good idea to stick to a regular procedure (hopefully a good one)
- when writing all your programs. Especially in code which starts and closes
- down your programs, it is possible and desirable to use a standard set of
- prewritten subroutines which can be modified as required.
-
- There are several rules that you should follow to produce good, safe code-
-
- 1. Always mirror opening and closing calls.
- 2. Always have ONE universal and thorough exit point.
- 3. Always make sure you close down everything you open, especially memory.
- 4. Always initialise variables correctly.
- 5. Always check memory available before and after using a program
- - if you are losing memory something is very wrong.
- 6. Always arrange your own output screen/window for serious programs
- - you can't use the interactive HeliOS window in stand-alone compiled
- code......because it won't be there!
-
-
- It is a good idea to use two standard start-up and close-down words for all
- your programs. Any special functions needed to start particular programs may
- be handled as single extra subroutine calls rather than all the code being
- included directly in your main startup subroutine.
-
-
- We include below simple source code for a program which:
-
- Has a simple structured "startup" word definition and a corresponding
- "closedown" routine. You can modify these for your own purposes and it
- would be a good idea to use them as a basis for all your early programs.
-
- Opens a custom screen
-
- Opens a window on the new screen
-
- Sets up graphic output to the new window and draws some graphics,
- including "graphic text"
-
- Sets up console text output in the new window and prints some text
-
- Sets up user input from the new window and waits for <SPACE> to
- be pressed.
-
- Uses an Amiga library call to show how it is done.
-
- Uses most of the things we have been discussing above......
-
-
- You will be surprised, perhaps, to see how easy all this is, and certainly
- you will be amazed how easy it is if you have used other Amiga programming
- languages which require you to do an enormous amount more preparatory work.
-
-
- Note:
-
- The following program is provided as a disk file called "TutorialProg.Src".
-
- Load this program into the HeliOS editor, as described for the small
- tutorial programs given earlier, then compile and run it.
-
-
- A typical start up program section might be as follows-
-
- FORGET **CORE** \ Clear the user dictionary
-
- D0 DVARIABLE SCREEN \ New Screen handle storage variable
- D0 DVARIABLE WINDOW \ Window handle store
-
- D0 DVARIABLE BITMAP \ Variables to store useful values, which.
- D0 DVARIABLE RASTPORT \ are collected at startup time in case of
- D0 DVARIABLE VIEW \ the need to use them later in graphics
- D0 DVARIABLE VIEWPORT \ related functions.
-
-
- \ OPENSYSTEM - Opens a screen and a window and sets up Input/Output.
- \ Includes an example of a library call for you to see
- \ Returns "1" on the stack for success and "0" for failure
-
-
- : OPENSYSTEM \ Start a colon definition, the new word is
- \ called, appropriately, "OPENSYSTEM"
-
- TIMEOFF \ Disable the time display in the HeliOS screen
-
- 0 HISTORY \ Disable the line editor's circular buffer
-
- 1 BAKSET \ Enable creation of Backup files on all disk
- \ SAVE operations - a useful safety feature
-
- \ These are all "general purpose" startup operations often used
-
-
- 1 STDSCREEN \ Initialises a standard NewScreen structure
- \ and sets Hires mode
-
- LIT$ $Tutorial Screen$ \ Specify the screen title bar text
-
- 640 250 \ Specify screen width and height
-
- 3 \ Depth of screen = number of bit planes
-
- OPENSCREEN \ Open a screen using the initialised structure
-
- SCREEN D! \ Store the screen handle/pointer
-
- SCREEN D@ \ Get SCREEN 32-bit pointer onto stack
-
-
- D0> \ Test if SCREEN is greater than zero
- \ This checks to see if screen opened OK
- \ If SCREEN is zero we have trouble.......
-
- IF \ If SCREEN is not zero we are OK.........
-
-
- SCREEN D@ \ Get 32-bit pointer to screen
-
- 44. \ Put double length number 44 on stack
-
- D+ \ Add this to screen pointer to give
- \ ViewPort pointer
-
- VIEWPORT D! \ Store the ViewPort for the new screen
-
- STDWINDOW \ Initialise a standard NewWindow structure
-
- HFWINDOW \ Modify the standard window for it to appear
- \ on the HeliOS Screen
-
- SCREEN D@ \ Get new screen again
-
- WINDOWSTRUCT \ Returns 16-bit pointer to NewWindow
-
- 30 + \ Add 30 to this
-
- D! \ Store screen pointer into NewWindow structure
-
- LIT$ $Tutorial Window$ \ Title bar text for window
-
- 0 12 640 238 \ Guess what....Window dimensions!
- 3 \ 3 BitPlanes
- 0 \ No SUPERBITMAP
- OPENWINDOW \ Open the new window
-
- WINDOW D! \ and store window pointer/handle
-
- WINDOW D@ \ Check if opened OK, like screen above
-
- D0> \ See "screen open" check above........
-
- IF
-
- WINDOW D@
- MAKEGFXWINDOW \ Enable graphics in this window
-
- WINDOW D@
- MAKEOUTWINDOW \ Enable text output to this window
-
- WINDOW D@
- MAKEINWINDOW \ Enable user input from this window
-
- WINDOW D@ \ Get Window pointer
-
- 50. D+ \ Add 50 to Window Pointer to get RastPort
-
- D@L \ Get RASTPORT pointer
-
- RASTPORT D! \ Get Window's RastPort, and store it in
- \ variable RASTPORT
-
- RASTPORT D@
- 4. D+ D@L
- BITMAP D! \ Get the bitmap from the stored RastPort
-
- INTUBASE \ Put on the stack the 16-bit address
- \ where the 32-bit pointer to Intuition
- \ library base is stored
-
- -294 \ Put on the stack the offset of the library
- \ call "ViewAddress"
-
- LIBRARY \ Call Intuition Library function to get
- \ VIEW pointer
-
- D0RESULT \ Get dummy register D0 value which is the
- \ View address returned from the library call
-
- VIEW D! \ Store pointer in variable VIEW
-
- 1 \ Put value "1" on stack to indicate that
- \ everything opened OK
- ELSE
- 0 \ Put "0" on stack to indicate failure
- THEN
- ELSE
- 0 \ Put "0" on stack to indicate failure
- THEN
- ; \ End of Colon Definition
-
-
- \ In a similar manner we have a defined a HeliOS word for the related
- \ close down routine -
-
-
- : CLOSESYSTEM \ Start the colon definition
-
- FORTHINWINDOW \ Redirect the input and output from
- FORTHOUTWINDOW \ program's window back to the HeliOS
- FWINDOW MAKEGFXWINDOW \ interactive environment
-
- WINDOW D@ \ Get contents of window handle store
- DFLAG \ Check and if Non-Zero put 1 on stack else
- \ put 0 on stack above window handle
-
- IF \ If window is open, ie handle is non zero
- CLOSEWINDOW \ Close it
- WINDOW D0! \ then set store to zero
- ELSE
- DDROP \ else cleanup stack (drop window handle)
- THEN \ end of If/Then structure
-
- SCREEN D@ \ Look at screen handle
- DFLAG IF \ If it is open......
- CLOSESCREEN
- SCREEN D0!
- ELSE
- DDROP
- THEN
-
- TIMEON \ Enable time display for the
- \ HeliOS screen before exiting
- ; \ End of colon definition
-
-
- \ Now we can use these functions in a small program:
-
-
- : TUTORIALPROGRAM
-
- OPENSYSTEM \ Open environment, returning 1 or 0
- \ indicating success or failure
-
- IF \ If 1 is returned, for "success"
-
- 1 GFXSETOPEN \ Set graphics outline pen colour to 1
-
- 1 GFXOUTLINE \ Switch on graphics OUTLINE mode
-
- 2 GFXSETAPEN \ Set graphics pen to "2" for circle
-
- 400 160 80 40 \ Circle coordinates
-
- GFXAREAELLIPSE \ Draw circle into off screen buffer
-
- GFXAREAEND \ Render circle to screen
-
- 0 GFXOUTLINE \ Switch off graphics OUTLINE mode
-
- 3 GFXSETAPEN \ Set graphics pen to "3" for text
-
- 100 200 GFXMOVE \ Set graphics pen position
-
- LIT$ $This is graphic text$ \ Text string
-
- COUNT \ Get text start and length
-
- GFXTEXT \ Output text
-
-
- 20 10 CURPUT \ Place cursor
-
- ." Hello....Press <SPACE> to exit!" \ Some console text output
-
-
- BEGIN \ Start a BEGIN/UNTIL construct
-
- KEY \ Wait for a keypress
-
- 32 \ ASCII code for <SPACE> is 32
-
- = \ See if KEY value = 32
-
- UNTIL \ Loop until result is TRUE
-
- THEN
-
- CLOSESYSTEM \ Close environment
- ;
-
- TUTORIALPROGRAM \ Actually execute the new "program" word.
-
- \ End of program
-
-
- *************************************************************************
-
- -------------------------------
- A few simple hints on debugging
- -------------------------------
-
- HeliOS has a very powerful user-configurable debugger, but for most
- debugging you should never need to use it! The following hints should
- be taken as general programming guidelines, and for detailed discussion
- of the HeliOS debugger you should refer to the debugger documentation.
-
- There are a few simple techniques which, combined with sensible programming
- strategies (for example, do not write 200k of source code altogether with
- no testing then expect it to work instantly...), will enable you to debug
- code very simply.
-
- When a bug occurs the program will often (probably!) crash.
-
- The best simple debugging technique is to put a repetitive debug line
- into the code up to and including the crash point.
-
- This line should display the stack status and wait for the space bar
- to be pressed. Something like the following will do nicely:
-
- ." Now at line xxx. Stack reads: " .S ." <SPACE> to continue" WAITSPACE CR
-
-
- A few of these lines included in your code will give you a sequential
- talk-through until the crash point is reached.
-
- Start with the high level code first and then work into your subroutines:
- in this way you can home in on the actual fault. It is good practice to
- check each subroutine thoroughly as it is completed, but nevertheless the
- most unexpected results can occur when even apparantly sound subroutines
- are used together in complex ways.
-
- The stack status message debug line suggested above will probably mess up
- your program's screen display, but that does not really matter in a debug
- operation.
-
- Always check for stack aberrations first. Be aware of what the stack should
- be reading and check your debug stack readouts scrupulously.
-
- If you like, include DUMP commands in your debug instructions to dump areas
- of memory for careful scrutiny.
-
- There are so many ways for code to fail it is impossible to cover all the
- aspects of debugging. Also debugging is a very intuitive thing and everyone
- has very personal preferences.
-
- The main thing is to never assume ANYTHING to be OK without double checking,
- and be prepared to be patient and check EVERYTHING relating to your problem
- with an open mind.
-
- Check your stack dumps minutely, dump and also check any areas of memory
- you think may be suspect, check variable values by including them in your
- debug lines where appropriate.
-
- One big source of trouble is using address pointers which should really be
- pointing at something useful like a screen structure address, but actually
- contain zero. For example, in our little program above, we checked that
- the screen had opened OK and that its returned value was not null. If we
- did not do this and then went on to use the screen handle, not realising
- that it was zero, terrible things would happen.....
-
- This sort of mistake is quite easy to make in more complex code, and can
- be very nasty. A golden rule on a multitasking machine like the Amiga
- is never to assume that an allocation or opening routine must always
- succeed. Always check to see if everything has opened correctly, and
- always take care to initialise all fields of data structures correctly.
-
- *************************************************************************
-
- -------------------
- Additional reading?
- -------------------
-
- Perhaps you are wondering whether HeliOS is similar to any other languages
- and whether you can get any books to help you learn to program?
-
- It is always useful to read a variety of documentary material when you are
- learning a new programming language because different authors will often
- give you very different and valuable insights.
-
- HeliOS is a threaded interpretive language derived from Forth, so many
- of its simplest commands are Forth oriented. A basic understanding of
- Forth (which is a much smaller language in scope than HeliOS) will
- certainly help you get started with HeliOS, and if you have access to
- any Forth textbooks these will give you a good idea of the way HeliOS
- programs are structured.
-
- HeliOS uses a stack for much of its parameter passing, as well as using
- reverse polish notation like Forth, so you will certainly benefit by
- reading about these concepts in any of the excellent Forth texbooks
- available. Forth text books will provide you with many helpful insights
- if you want to read them as background information: however, you should
- beware of taking the analogy between Forth and HeliOS too far. The fact
- is that the similarity between the languages is superficial and sometimes
- deceptive, so take care not to learn false ideas.
-
- As a Forth instructional text we advise you to purchase Leo Brodie's
- excellent text "Starting Forth", published by Prentice Hall in paperback.
-
- You will certainly need to study specialised texts on the Amiga if you
- want to get the best out of HeliOS because HeliOS, like "C", makes use of
- the Amiga operating system and also allows direct Amiga hardware control.
-
- The Addison-Wesley Amiga manuals are an excellent investment if you are
- serious about Amiga programming, and Compute Books' "Mapping the Amiga"
- is an extremely useful reference text.
-
- HeliOS can supply an excellent comprehensive set of example programs on
- all HeliOS commands written by Sebastien Veyrin-Forrer. These short
- example programs detail the use of every word in the HeliOS vocabulary.
-
- ----------------------------------------------------------------------
- End
- ----------------------------------------------------------------------
-