@database beginner.guide 

@Master beginner 

@Width 75 


This is the AmigaGuideŽ file beginner.guide, produced by Makeinfo-1.55 from 
the input file beginner.


@NODE "main" "E Built-In Constants Variables and Functions"
@Next "Modules.guide/main" 
@Prev "MoreExpressions.guide/main" 
@Toc "Contents.guide/main" 

E Built-In Constants, Variables and Functions
*********************************************

   This chapter describes the constants, variables and functions which are
built in to the E language.  You can add more by using modules, but that's
a more advanced topic (see @{"Modules" Link "Modules.guide/main" }).


 @{" Built-In Constants " Link "Built-In Constants" } 
 @{" Built-In Variables " Link "Built-In Variables" } 
 @{" Built-In Functions " Link "Built-In Functions" } 


@ENDNODE

@NODE "Built-In Constants" "Built-In Constants"
@Next "Built-In Variables" 
@Toc "main" 

Built-In Constants
==================

   We've already met several built-in constants.  Here's the complete list:

@{b }TRUE@{ub },  @{b }FALSE@{ub }
     The boolean constants.  As numbers, @{b }TRUE@{ub } is -1 and @{b }FALSE@{ub } is zero.

@{b }NIL@{ub }
     The bad pointer value.  Several functions produce this value for a
     pointer if an error occurred.  As a number, @{b }NIL@{ub } is zero.

@{b }ALL@{ub }
     Used with string and list functions to indicate that all the string
     or list is to be used.  As a number, @{b }ALL@{ub } is -1.

@{b }GADGETSIZE@{ub }
     The minimum number of bytes required to hold all the data for one
     gadget.  See @{"Intuition support functions" Link "Intuition support functions" }.

@{b }OLDFILE@{ub },  @{b }NEWFILE@{ub }
     Used with @{b }Open@{ub } to open an old or new file.  See the `AmigaDOS Manual'
     for more details.

@{b }STRLEN@{ub }
     The length of the last string constant used.  Remember that a string
     constant is something between @{b }'@{ub } characters, so, for example, the
     following program prints the string @{b }s@{ub } and then its length:

          PROC main()
            DEF s:PTR TO CHAR, len
            s:='12345678'
            len:=STRLEN
            WriteF(s)
            WriteF('\\nis \\d characters long\\n', len)
          ENDPROC


@ENDNODE

@NODE "Built-In Variables" "Built-In Variables"
@Next "Built-In Functions" 
@Prev "Built-In Constants" 
@Toc "main" 

Built-In Variables
==================

   The following variables are built in to E and are called @{fg shine }system
variables@{fg text }.  They are global so can be accessed from any procedure.

@{b }arg@{ub }
     This is a string which contains the @{fg shine }command line@{fg text } arguments passed
     your program when it was run (from the Shell or CLI).  For instance,
     if your program were called @{b }fred@{ub } and you ran it like this:

          fred file.txt "a big file" another

     then @{b }arg@{ub } would the string:

          file.txt "a big file" another

     If you have AmigaDOS 2.0 (or greater) you can use the system routine
     @{b }ReadArgs@{ub } to parse the command line in a much more versatile way.
     There is a worked example on argument parsing in Part Three (see
     @{"Argument Parsing" Link "Examples.guide/Argument Parsing" }).

@{b }wbmessage@{ub }
     This contains @{b }NIL@{ub } if your program was started from the Shell/CLI,
     otherwise it's a pointer to the Workbench message which contains
     information about the icons selected when you started the program
     from Workbench.  So, if you started the program from Workbench
     @{b }wbmessage@{ub } will not be @{b }NIL@{ub } and it will contain the Workbench
     arguments, but if you started the program from the Shell/CLI
     @{b }wbmessage@{ub } will be @{b }NIL@{ub } and the argments will be in @{b }arg@{ub } (or via
     @{b }ReadArgs@{ub }).  There is a worked example on argument parsing in Part
     Three (see @{"Argument Parsing" Link "Examples.guide/Argument Parsing" }).

@{b }stdin@{ub }, @{b }stdout@{ub },  @{b }conout@{ub }
     The @{b }stdin@{ub } and @{b }stdout@{ub } variables contain the standard input and output
     filehandles.  If your program was started from the Shell/CLI they
     will be filehandles on the Shell/CLI window (and @{b }conout@{ub } will be @{b }NIL@{ub }).
     However, if your program was started from Workbench these will both
     be @{b }NIL@{ub }, and in this case the first call to @{b }WriteF@{ub } will open an output
     @{b }CON:@{ub } window and store the file handle for the window in @{b }stdout@{ub } and
     @{b }conout@{ub }.  The file handle stored in @{b }conout@{ub } will be closed using @{b }Close@{ub }
     when the program terminates, so you can set up your own @{b }CON:@{ub } window
     or file for use by the output functions and have it automatically
     closed.  See @{"Input and output functions" Link "Input and output functions" }.

@{b }stdrast@{ub }
     The raster port used by E built-in graphics functions such as @{b }Box@{ub } and
     @{b }Plot@{ub }.  This can be changed so that these functions draw on different
     screens etc.  See @{"Graphics functions" Link "Graphics functions" }.

@{b }dosbase@{ub },  @{b }execbase@{ub },  @{b }gfxbase@{ub },  @{b }intuitionbase@{ub }
     These are pointers to the appropriate library base, and are
     initialised by the E startup code, i.e., the Dos, Exec, Graphics and
     Intuition libraries are all opened by E so you don't need to do it
     yourself.  These libraries are also automatically closed by E, so you
     shouldn't close them yourself.  However, you must explicitly open and
     close all other Amiga system libraries that you want to use.  The
     other library base variables are defined in the accompanying module
     (see @{"Modules" Link "Modules.guide/main" }).


@ENDNODE

@NODE "Built-In Functions" "Built-In Functions"
@Prev "Built-In Variables" 
@Toc "main" 

Built-In Functions
==================

   There are many built-in functions in E. We've already seen a lot of
string and list functions, and we've used @{b }WriteF@{ub } for printing.  The
remaining functions are, generally, simplifications of complex Amiga
system functions, or E versions of support functions found in languages
like C and Pascal.

   To understand the graphics and Intuition support functions completely
you really need to get something like the `Rom Kernel Reference Manual
(Libraries)'.  However, if you don't want to do anything too complicated
you should be able to get by.


 @{" Input and output functions " Link "Input and output functions" } 
 @{" Intuition support functions " Link "Intuition support functions" } 
 @{" Graphics functions " Link "Graphics functions" } 
 @{" Maths and logic functions " Link "Maths and logic functions" } 
 @{" System support functions " Link "System support functions" } 


@ENDNODE

@NODE "Input and output functions" "Input and output functions"
@Next "Intuition support functions" 
@Toc "Built-In Functions" 

Input and output functions
--------------------------

@{b }WriteF(@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }param1@{fg text }@{b },@{ub }@{fg shine }param2@{fg text }@{b },...)@{ub } 
     Writes a string to the standard output and returns the number of
     characters written.  If place-holders are used in the string then the
     appropriate number of parameters must be supplied after the string in
     the order they are to be printed as part of the string.  So far we've
     only met the @{b }\\d@{ub } place-holder for decimal numbers.  The complete list
     is:

          @{i }Place-Holder@{ui }  @{i }Parameter Type@{ui }   @{i }Prints@{ui }
          -------------------------------------------------
               \\c          Number        Character
               \\d          Number        Decimal number
               \\h          Number        Hexadecimal number
               \\s          String        String

     So to print a string you use the @{b }\\s@{ub } place-holder in the string and
     supply the string (i.e., a @{b }PTR TO CHAR@{ub }) as a parameter.  Try the
     following program (remember @{b }\\a@{ub } prints an apostrophe character):

          PROC main()
            DEF s[30]:STRING
            StrCopy(s, 'Hello world', ALL)
            WriteF('The third element of s is "\\c"\\n', s[2])
            WriteF('or \\d (decimal)\\n',                s[2])
            WriteF('or \\h (hexadecimal)\\n',            s[2])
            WriteF('and s itself is \\a\\s\\a\\n',         s)
          ENDPROC

     This is the output it generates:

          The third element of s is "l"
          or 108 (decimal)
          or 6C (hexadecimal)
          and s itself is 'Hello world'

     You can control how the parameter is formatted in the @{b }\\d@{ub }, @{b }\\h@{ub } and
     @{b }\\s@{ub } fields using another collection of special character
     sequences before the place-holder and size specifiers after it.  If
     no size is specified the field will be as big as the data requires.
     A fixed field size can be specified using @{b } [@{ub }@{fg shine }number@{fg text }@{b }]@{ub } after the
     place-holder.  For strings you can also use the size specifier
     @{b } (@{ub }@{fg shine }min@{fg text }@{b },@{ub }@{fg shine }max@{fg text }@{b })@{ub } which specifies the minimum and
     maximum sizes of the field.  By default the data is right justified
     in the field and the left part of the field is filled, if necessary,
     with spaces.  The following sequences before the place-holder can
     change this:

          @{i }Sequence@{ui }        @{i }Meaning@{ui }
          -----------------------------------
             \\l     Left justify in field
             \\r     Right justify in field
             \\z     Set fill character to "0"

     See how these formatting controls affect this example:

          PROC main()
            DEF s[30]:STRING
            StrCopy(s, 'Hello world', ALL)
            WriteF('The third element of s is "\\c"\\n', s[2])
            WriteF('or \\d[4] (decimal)\\n',             s[2])
            WriteF('or \\z\\h[4] (hexadecimal)\\n',       s[2])
            WriteF('\\a\\s[5]\\a are the first five elements of s \\n', s)
            WriteF('and s in a very big field  \\a\\s[20]\\a\\n',   s)
            WriteF('and s left justified in it \\a\\l\\s[20]\\a\\n', s)
          ENDPROC

     Here's the output it should generate:

          The third element of s is "l"
          or  108 (decimal)
          or 006C (hexadecimal)
          'Hello' are the first five elements of s
          and s in a very big field  '         Hello world'
          and s left justified in it 'Hello world         '

     @{b }WriteF@{ub } uses the standard output, and this file handle is stored in
     the @{b }stdout@{ub } variable.  If your program is started from Workbench this
     variable will contain @{b }NIL@{ub }.  In this case, the first call to @{b }WriteF@{ub }
     will open a special output window and put the file handle in the
     variables @{b }stdout@{ub } and @{b }conout@{ub }, as outlined above (see
     @{"Built-In Variables" Link "Built-In Variables" }).

@{b }PrintF(@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }param1@{fg text }@{b },@{ub }@{fg shine }param2@{fg text }@{b },...)@{ub } 
     @{b }PrintF@{ub } works just like @{b }WriteF@{ub } except it uses the more efficient,
     buffered output routines only available if your Amiga is using
     Kickstart version 37 or greater (i.e., AmigaDOS 2.04 and above).

@{b }StringF(@{ub }@{fg shine }e-string@{fg text }@{b },@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }arg1@{fg text }@{b },@{ub }@{fg shine }arg2@{fg text }@{b },...)@{ub } 
     The same as @{b }WriteF@{ub } except that the result is written to @{fg shine }e-string@{fg text }
     instead of being printed.  For example, the following code fragment
     sets @{b }s@{ub } to @{b }00123 is a@{ub } (since the E-string is not long enough for the
     whole string):

            DEF s[10]:STRING
            StringF(s, '\\z\\d[5] is a number', 123)

@{b }Out(@{ub }@{fg shine }filehandle@{fg text }@{b },@{ub }@{fg shine }char@{fg text }@{b })@{ub } 
     Outputs a single character, @{fg shine }char@{fg text }, to the file or console window
     denoted by @{fg shine }filehandle@{fg text }, and returns -1 to indicate success (so any
     other return value means an error occurred).  For instance,
     @{fg shine }filehandle@{fg text } could be @{b }stdout@{ub }, in which case the character is written
     to the standard output.  (You need to make sure @{b }stdout@{ub } is not @{b }NIL@{ub },
     and you can do this by using a @{b }WriteF('')@{ub } call.) In general, you
     obtain a filehandle using the Amiga system function @{b }Open@{ub } from the
     @{b }dos.library@{ub } (see @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }).

@{b }Inp(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } 
     Reads and returns a single character from @{fg shine }filehandle@{fg text }.  If -1 is
     returned then the end of the file (EOF) was reached, or there was an
     error.

@{b }ReadStr(@{ub }@{fg shine }filehandle@{fg text }@{b },@{ub }@{fg shine }e-string@{fg text }@{b })@{ub } 
     Reads a whole string from @{fg shine }filehandle@{fg text } and returns -1 if EOF was
     reached or an error occurred.  Characters are read up to a linefeed
     or the size of the string, whichever is sooner.  Therefore, the
     resulting string may be only a partial line.  If -1 is returned then
     EOF was reached or an error occurred, and in either case the string
     so far is still valid.  So, you still need to check the string even
     if -1 is returned.  (This will most commonly happen with files that
     do not end with a linefeed.) The string will be empty (i.e., of zero
     length) if nothing more had been read from the file when the error or
     EOF happened.

     This next little program reads continually from its input until an
     error occurs or the user types @{b }quit@{ub }.  It echoes the lines that it
     reads in uppercase.  If you type a line longer than ten characters
     you'll see it reads it in more than one go.  Because of the way
     normal console windows work, you need to type a return before a line
     gets read by the program (but this allows you to edit the line before
     the program sees it).  If the program is started from Workbench then
     @{b }stdin@{ub } would be @{b }NIL@{ub }, so @{b }WriteF('')@{ub } is used to force @{b }stdout@{ub } to be
     valid, and in this case it will be a new console window which can be
     used to accept input!  (To make the compiled program into a Workbench
     program you simply need to create a tool icon for it.  A quick way of
     doing this is to copy an existing tool's icon.)

          PROC main()
            DEF s[10]:STRING, fh
            WriteF('')
            fh:=IF stdin THEN stdin ELSE stdout
            WHILE ReadStr(fh, s)<>-1
              UpperStr(s)
            EXIT StrCmp(s, 'QUIT', ALL)
              WriteF('Read: \\a\\s\\a\\n', s)
            ENDWHILE
            WriteF('Finished\\n')
          ENDPROC

     There are some worked examples in Part Three (see
     @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }) which also show how to use @{b }ReadStr@{ub }.

@{b }FileLength(@{ub }@{fg shine }string@{fg text }@{b })@{ub } 
     Returns the length of the file named in @{fg shine }string@{fg text }, or -1 if the file
     doesn't exist or an error occurred.  Notice that you don't need to
     @{b }Open@{ub } the file or have a filehandle, you just supply the filename.
     There is a worked example in Part Three (see @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" })
     which shows how to use this function.

@{b }SetStdIn(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } 
     Returns the value of @{b }stdin@{ub } before setting it to @{fg shine }filehandle@{fg text }.
     Therefore, the following code fragments are equivalent:

            oldstdin:=SetStdIn(newstdin)
          
            oldstdin:=stdin
            stdin:=newstdin

@{b }SetStdOut(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } 
     Returns the value of @{b }stdout@{ub } before setting it to @{fg shine }filehandle@{fg text }, and is
     otherwise just like @{b }SetStdIn@{ub }.


@ENDNODE

@NODE "Intuition support functions" "Intuition support functions"
@Next "Graphics functions" 
@Prev "Input and output functions" 
@Toc "Built-In Functions" 

Intuition support functions
---------------------------

   The functions in this section are simplified versions of Amiga system
functions (in the Intuition library, as the title suggests).  To make best
use of them you are probably going to need something like the `Rom Kernel
Reference Manual (Libraries)', especially if you want to understand the
Amiga specific things like IDCMP and raster ports.

   The descriptions given here vary slightly in style from the previous
descriptions.  All function parameters can be expressions which represent
numbers or addresses, as appropriate.  Because many of the functions take
several parameters they have been named (fairly descriptively) so they can
be more easily referenced.

@{b }OpenW(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }wid@{fg text }@{b },@{ub }@{fg shine }hgt@{fg text }@{b },@{ub }@{fg shine }idcmp@{fg text }@{b },@{ub }@{fg shine }wflgs@{fg text }@{b },@{ub }@{fg shine }title@{fg text }@{b },@{ub }@{fg shine }scrn@{fg text }@{b },@{ub }@{fg shine }sflgs@{fg text }@{b },@{ub }@{fg shine }gads@{fg text }@{b },@{ub }@{fg shine }tags@{fg text }@{b }=NIL)@{ub } 
     Opens and returns a pointer to a window with the supplied properties.
     If for some reason the window could not be opened @{b }NIL@{ub } is returned.

    @{fg shine }x@{fg text },  @{fg shine }y@{fg text }
          The position on the screen where the window will appear.

    @{fg shine }wid@{fg text },  @{fg shine }hgt@{fg text }
          The width and height of the window.

    @{fg shine }idcmp@{fg text },  @{fg shine }wflgs@{fg text }
          The IDCMP and window specific flags.

    @{fg shine }title@{fg text }
          The window title (a string) which appears on the title bar of
          the window.

    @{fg shine }scrn@{fg text },  @{fg shine }sflgs@{fg text }
          The screen on which the window should open.  If @{fg shine }sflgs@{fg text } is 1 the
          window will be opened on Workbench, and @{fg shine }scrn@{fg text } is ignored (so it
          can be @{b }NIL@{ub }).  If @{fg shine }sflgs@{fg text } is @{b }$F@{ub } (i.e., 15) the window will open
          on the custom screen pointed to by @{fg shine }scrn@{fg text } (which must then be
          valid).  See @{b }OpenS@{ub } to see how to open a custom screen and get a
          screen pointer.

    @{fg shine }gads@{fg text }
          A pointer to a gadget list, or @{b }NIL@{ub } if you don't want any gadgets.
          These are not the standard window gadgets, since they are
          specified using  the window flags.  A gadget list can be created
          using the @{b }Gadget@{ub } function.

    @{fg shine }tags@{fg text }
          A tag-list of other options available under Kickstart version 37
          or greater.  This can normally be omitted since it defaults to
          @{b }NIL@{ub }.  See the `Rom Kernel Reference Manual (Libraries)' for
          details about the available tags and their meanings.

     There's not enough space to describe all the fine details about
     windows and IDCMP (see the `Rom Kernel Reference Manual (Libraries)'
     for complete details), but a brief description in terms of flags
     might be useful.  Here's a small table of common IDCMP flags:

          @{i }IDCMP Flag@{ui }           @{i }Value@{ui }
          --------------------------
          IDCMP_NEWSIZE           $2
          IDCMP_REFRESHWINDOW     $4
          IDCMP_MOUSEBUTTONS      $8
          IDCMP_MOUSEMOVE        $10
          IDCMP_GADGETDOWN       $20
          IDCMP_GADGETUP         $40
          IDCMP_MENUPICK        $100
          IDCMP_CLOSEWINDOW     $200
          IDCMP_RAWKEY          $400
          IDCMP_DISKINSERTED   $8000
          IDCMP_DISKREMOVED   $10000

     Here's a table of useful window flags:

          @{i }Window Flag@{ui }          @{i }Value@{ui }
          --------------------------
          WFLG_SIZEGADGET         $1
          WFLG_DRAGBAR            $2
          WFLG_DEPTHGADGET        $4
          WFLG_CLOSEGADGET        $8
          WFLG_SIZEBRIGHT        $10
          WFLG_SIZEBBOTTOM       $20
          WFLG_SMART_REFRESH       0
          WFLG_SIMPLE_REFRESH    $40
          WFLG_SUPER_BITMAP      $80
          WFLG_BACKDROP         $100
          WFLG_REPORTMOUSE      $200
          WFLG_GIMMEZEROZERO    $400
          WFLG_BORDERLESS       $800
          WFLG_ACTIVATE        $1000

     All these flags are defined in the module @{b }intuition/intuition@{ub }, so if
     you use that module you can use the constants rather than having to
     write the less descriptive value (see @{"Modules" Link "Modules.guide/main" }).  Of course, you can
     always define your own constants for the values that you use.

     You use the flags by @{b }OR@{ub }-ing the ones you want together, in a similar
     way to using sets (see @{"Sets" Link "Constants.guide/Sets" }).  However, you should supply only IDCMP
     flags as part of the @{fg shine }idcmp@{fg text } parameter, and you should supply only
     window flags as part of the @{fg shine }wflgs@{fg text } parameter.  So, to get IDCMP
     messages when a disk is inserted and when the close gadget is clicked
     you specify both of the flags @{b }IDCMP_DISKINSERTED@{ub } and
     @{b }IDCMP_CLOSEWINDOW@{ub } for the @{fg shine }idcmp@{fg text } parameter, either by @{b }OR@{ub }-ing the
     constants or (less readably) by using the calculated value @{b }$8200@{ub }.

     Some of the window flags require some of IDCMP flags to be used as
     well, if an effect is to be complete.  For example, if you want your
     window to have a close gadget (a standard window gadget) you need to
     use @{b }WFLG_CLOSEGADGET@{ub } as one of the window flags.  If you want that
     gadget to be useful then you need to get an IDCMP message when the
     gadget is clicked.  You therefore need to use @{b }IDCMP_CLOSEWINDOW@{ub } as
     one of the IDCMP flags.  So the full effect requires both a window
     and an IDCMP flag (a gadget is pretty useless if you can't tell when
     it's been clicked).  The worked example in Part Three illustrates how
     to use these flags in this way (see @{"Gadgets" Link "Examples.guide/Gadgets" }).

     If you only want to output text to a window (and maybe do some input
     from a window), it may be better to use a @{fg shine }console@{fg text } window.  These
     provide a text based input and output window, and are opened using
     the Dos library function @{b }Open@{ub } with the appropriate @{b }CON:@{ub } file name.
     See the `AmigaDOS Manual' for more details about console windows.

@{b }CloseW(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     Closes the window which is pointed to by @{fg shine }winptr@{fg text }.  It's safe to give
     @{b }NIL@{ub } for @{fg shine }winptr@{fg text }, but in this case, of course, no window will be
     closed!  The window pointer is usually a pointer returned by a
     matching call to @{b }OpenW@{ub }.  You @{i }must@{ui } remember to close any windows you
     may have opened before terminating your program.

@{b }OpenS(@{ub }@{fg shine }wid@{fg text }@{b },@{ub }@{fg shine }hgt@{fg text }@{b },@{ub }@{fg shine }depth@{fg text }@{b },@{ub }@{fg shine }scrnres@{fg text }@{b },@{ub }@{fg shine }title@{fg text }@{b },@{ub }@{fg shine }tags@{fg text }@{b }=NIL)@{ub } 
     Opens and returns a pointer to a custom screen with the supplied
     properties.  If for some reason the screen could not be opened @{b }NIL@{ub } is
     returned.

    @{fg shine }wid@{fg text },  @{fg shine }hgt@{fg text }
          The width and height of the screen.

    @{fg shine }depth@{fg text }
          The depth of the screen, i.e., the number of bit-planes.  This
          can be a number in the range 1-8 for AGA machines, or 1-6 for
          pre-AGA machines.  A screen with depth 3 will be able to show 2
          to the power 3 (i.e., 8) different colours, since it will have 2
          to the power 3 different pens (or colour registers) available.
          You can set the colours of pens using the @{b }SetColour@{ub } function.

    @{fg shine }scrnres@{fg text }
          The screen resolution flags.

    @{fg shine }title@{fg text }
          The screen title (a string) which appears on the title bar of
          the screen.

    @{fg shine }tags@{fg text }
          A tag-list of other options available under Kickstart version 37
          or greater.  See the `Rom Kernel Reference Manual (Libraries)'
          for more details.

     The screen resolution flags control the screen mode.  The following
     (common) values are taken from the module @{b }graphics/view@{ub } (see @{"Modules" Link "Modules.guide/main" }).
     You can, if you want, define your own constants for the values that
     you use.  Either way it's best to use descriptive constants rather
     than directly using the values.

          @{i }Mode Flag@{ui }          @{i }Value@{ui }
          ------------------------
          V_LACE                $4
          V_SUPERHIRES         $20
          V_PFBA               $40
          V_EXTRA_HALFBRITE    $80
          V_DUALPF            $400
          V_HAM               $800
          V_HIRES            $8000

     So, to get a hires, interlaced screen you specify both of the flags
     @{b }V_HIRES@{ub } and @{b }V_LACE@{ub }, either by @{b }OR@{ub }-ing the constants or (less readably)
     by using calculated value @{b }$8004@{ub }.  There is a worked example using
     this function in Part Three (see @{"Screens" Link "Examples.guide/Screens" }).

@{b }CloseS(@{ub }@{fg shine }scrnptr@{fg text }@{b })@{ub } 
     Closes the screen which is pointed to by @{fg shine }scrnptr@{fg text }.  It's safe to
     give @{b }NIL@{ub } for @{fg shine }scrnptr@{fg text }, but in this case, of course, no screen will
     be closed!  The screen pointer is usually a pointer returned by a
     matching call to @{b }OpenS@{ub }.  You @{i }must@{ui } remember to close any screens you
     may have opened before terminating your program.  Also, you @{i }must@{ui }
     close all windows that you opened on your screen before you can close
     the screen.

@{b }Gadget(@{ub }@{fg shine }buf@{fg text }@{b },@{ub }@{fg shine }glist@{fg text }@{b },@{ub }@{fg shine }id@{fg text }@{b },@{ub }@{fg shine }flags@{fg text }@{b },@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }width@{fg text }@{b },@{ub }@{fg shine }text@{fg text }@{b })@{ub } 
     Creates a new gadget with the supplied properties and returns a
     pointer to the next position in the (memory) buffer that can be used
     for a gadget.

    @{fg shine }buf@{fg text }
          This is the memory buffer, i.e., a chunk of allocated memory.
          The best way of allocating this memory is to declare an array of
          size n*GADGETSIZE, where @{fg shine }n@{fg text } is the number of gadgets which are
          going to be created.  The first call to @{b }Gadget@{ub } will use the
          array as the buffer, and subsequent calls use the result of the
          previous call as the buffer (since this function returns the
          next free position in the buffer).

    @{fg shine }glist@{fg text }
          This is a pointer to the gadget list that is being created,
          i.e., the array used as the buffer.  When you create the first
          gadget in the list using an array @{b }a@{ub }, this parameter should be
          @{b }NIL@{ub }.  For all other gadgets in the list this parameter
          should be the array @{b }a@{ub }.

    @{fg shine }id@{fg text }
          A number which identifies the gadget.  It is best to give a
          unique number for each gadget; that way you can easily identify
          them.  This number is the only way you can identify which gadget
          has been clicked.

    @{fg shine }flags@{fg text }
          The type of gadget to be created.  Zero represents a normal
          gadget, one a boolean gadget (a toggle) and three a boolean that
          starts selected.

    @{fg shine }x@{fg text },  @{fg shine }y@{fg text }
          The position of the gadget, relative to the top, left-hand
          corner of the window.

    @{fg shine }width@{fg text }
          The width of the gadget (in pixels, not characters).

    @{fg shine }text@{fg text }
          The text (a string) which will centred in the gadget, so the
          @{fg shine }width@{fg text } must be big enough to hold this text.

     Once a gadget list has been created by possibly several calls to this
     function the list can be passed as the @{fg shine }gads@{fg text } parameter to @{b }OpenW@{ub }.
     There is a worked example using this function in Part Three (see
     @{"Gadgets" Link "Examples.guide/Gadgets" }).

@{b }Mouse()@{ub } 
     Returns the state of the mouse buttons (including the middle mouse
     button if you have a three-button mouse).  This is a set of flags,
     and the individual flag values are:

          @{i }Button Pressed@{ui }   @{i }Value@{ui }
          ----------------------
          Left              %001
          Right             %010
          Middle            %100

     So, if this function returns @{b }%001@{ub } you know the left button is being
     pressed, and if it returns @{b }%110@{ub } you know the middle and right buttons
     are both being pressed.

     This mouse function is not strictly the proper way to do things.  It
     is suggested you use this function only for small tests or demo-like
     programs.  @{b }LeftMouse@{ub } and @{b }WaitLeftMouse@{ub } can be used to do things in a
     friendly way, but are restricted to seeing when the left mouse button
     is pressed.  More generally, the proper way of getting mouse details
     is to use the appropriate IDCMP flags for your window, wait for
     events (using @{b }WaitIMessage@{ub }, for example) and decode the received
     information.

@{b }MouseX(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     Returns the @{fg shine }x@{fg text } coordinate of the mouse pointer, relative to the
     window pointed to by @{fg shine }winptr@{fg text }.

     As above, this mouse function is not strictly the proper way to do
     things.

@{b }MouseY(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     Returns the @{fg shine }y@{fg text } coordinate of the mouse pointer, relative to the
     window pointed to by @{fg shine }winptr@{fg text }.

     As above, this mouse function is not strictly the proper way to do
     things.

@{b }LeftMouse(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     Returns @{b }TRUE@{ub } if left mouse button has been clicked in the window
     pointed to by @{fg shine }winptr@{fg text }, and @{b }FALSE@{ub } otherwise.  In order for this to
     work sensibly the window must have the IDCMP flag @{b }IDCMP_MOUSEBUTTONS@{ub }
     set (see above).

     This function does things in a proper, Intuition-friendly manner and
     so is a good alternative to the @{b }Mouse@{ub } function.

@{b }WaitIMessage(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     This function waits for a message from Intuition for the window
     pointed to by @{fg shine }winptr@{fg text } and returns the class of the message (which is
     an IDCMP flag).  If you did not specify any IDCMP flags when the
     window was opened, or the specified messages could never happen
     (e.g., you asked only for gadget messages and you have no gadgets),
     then this function may wait forever.  When you've got a message you
     can use the @{b }MsgXXX@{ub } functions to get some more information about the
     message.  See the `Rom Kernel Reference Manual (Libraries)' for more
     details on Intuition and IDCMP.  There is a worked example using this
     function in Part Three (see @{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }).

     This function is basically equivalent to the following function,
     except that the @{b }MsgXXX@{ub } functions can also access the message data
     held in the variables @{b }code@{ub }, @{b }qual@{ub } and @{b }iaddr@{ub }.

          PROC waitimessage(win:PTR TO window)
            DEF port,msg:PTR TO intuimessage,class,code,qual,iaddr
            port:=win.userport
            IF (msg:=GetMsg(port))=NIL
              REPEAT
                WaitPort(port)
              UNTIL (msg:=GetMsg(port))<>NIL
            ENDIF
            class:=msg.class
            code:=msg.code
            qual:=msg.qualifier
            iaddr:=msg.iaddress
            ReplyMsg(msg)
          ENDPROC class

@{b }MsgCode()@{ub } 
     Returns the @{b }code@{ub } part of the message returned by @{b }WaitIMessage@{ub }.

@{b }MsgIaddr()@{ub } 
     Returns the @{b }iaddr@{ub } part of the message returned by @{b }WaitIMessage@{ub }.
     There is a worked example using this function in Part Three (see
     @{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }).

@{b }MsgQualifier()@{ub } 
     Returns the @{b }qual@{ub } part of the message returned by @{b }WaitIMessage@{ub }.

@{b }WaitLeftMouse(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } 
     This function waits for the left mouse button to be clicked in the
     window pointed to by @{fg shine }winptr@{fg text }.  It is advisable to have the IDCMP
     flag @{b }IDCMP_MOUSEBUTTONS@{ub } set for the window (see above).

     This function does things in a proper, Intuition-friendly manner and
     so is a good alternative to the @{b }Mouse@{ub } function.


@ENDNODE

@NODE "Graphics functions" "Graphics functions"
@Next "Maths and logic functions" 
@Prev "Intuition support functions" 
@Toc "Built-In Functions" 

Graphics functions
------------------

   The functions in this section use the standard raster port, the address
of which is held in the variable @{b }stdrast@{ub }.  Most of the time you don't need
to worry about this because the E functions which open windows and screens
set up this variable (see @{"Intuition support functions" Link "Intuition support functions" }).  So, by default,
these functions affect the last window or screen opened.  When you close a
window or screen, @{b }stdrast@{ub } becomes @{b }NIL@{ub } and calls to these functions have no
effect.  There is a worked example using these functions in Part Three
(see @{"Graphics" Link "Examples.guide/Graphics" }).

   The descriptions in this section follow the same style as the previous
section.

@{b }Plot(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } 
     Plots a single point (@{fg shine }x@{fg text },@{fg shine }y@{fg text }) in the specified pen colour.  The
     position is relative to the top, left-hand corner of the window or
     screen that is the current raster port (normally the last screen or
     window to be opened).  The range of pen values available depend on
     the screen setup, but are at best 0-255 on AGA machines and 0-31 on
     pre-AGA machines.  As a guide, the background colour is usually pen
     zero, and the main foreground colour is pen one (and this is the
     default pen).  You can set the colours of pens using the @{b }SetColour@{ub }
     function.

@{b }Line(@{ub }@{fg shine }x1@{fg text }@{b },@{ub }@{fg shine }y1@{fg text }@{b },@{ub }@{fg shine }x2@{fg text }@{b },@{ub }@{fg shine }y2@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } 
     Draws the line (@{fg shine }x1@{fg text },@{fg shine }y1@{fg text }) to (@{fg shine }x2@{fg text },@{fg shine }y2@{fg text }) in the specified pen colour.

@{b }Box(@{ub }@{fg shine }x1@{fg text }@{b },@{ub }@{fg shine }y1@{fg text }@{b },@{ub }@{fg shine }x2@{fg text }@{b },@{ub }@{fg shine }y2@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } 
     Draws the (filled) box with vertices (@{fg shine }x1@{fg text },@{fg shine }y1@{fg text }), (@{fg shine }x2@{fg text },@{fg shine }y1@{fg text }),
     (@{fg shine }x1@{fg text },@{fg shine }y2@{fg text }) and (@{fg shine }x2@{fg text },@{fg shine }y2@{fg text }) in the
     specified pen colour.

@{b }Colour(@{ub }@{fg shine }fore-pen@{fg text }@{b },@{ub }@{fg shine }back-pen@{fg text }@{b }=0)@{ub } 
     Sets the foreground and background pen colours.  As mentioned above,
     the background colour is normally pen zero and the main foreground is
     pen one.  You can change these defaults with this function, and if
     you stick to having the background pen as pen zero then calling this
     function with one argument changes just the foreground pen.

@{b }TextF(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }format-string@{fg text }@{b },@{ub }@{fg shine }arg1@{fg text }@{b },@{ub }@{fg shine }arg2@{fg text }@{b },...)@{ub } 
     This works just like @{b }WriteF@{ub } except the resulting string is drawn on
     the current raster port (usually the last window or screen to be
     opened) ,starting at point (@{fg shine }x@{fg text },@{fg shine }y@{fg text }).  Take care not to use any
     line-feed, carriage return, tab or escape characters in the
     string--they don't behave like they do in @{b }WriteF@{ub }.

@{b }SetColour(@{ub }@{fg shine }scrnptr@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b },@{ub }@{fg shine }r@{fg text }@{b },@{ub }@{fg shine }g@{fg text }@{b },@{ub }@{fg shine }b@{fg text }@{b })@{ub } 
     Sets the colour of colour register @{fg shine }pen@{fg text } for the screen pointed to by
     @{fg shine }scrnptr@{fg text } to be the appropriate RGB value (i.e., red value @{fg shine }r@{fg text }, green
     value @{fg shine }g@{fg text } and blue value @{fg shine }b@{fg text }).  The @{b }pen@{ub } can be anything up to 255,
     depending on the screen depth.  Regardless of the chipset being used,
     @{fg shine }r@{fg text }, @{fg shine }g@{fg text } and @{fg shine }b@{fg text } are taken from the range zero to 255, so 24-bit
     colours are always specified.  In operation, though, the values are
     scaled to 12-bit colour for non-AGA machines.

@{b }SetStdRast(@{ub }@{fg shine }newrast@{fg text }@{b })@{ub } 
     Returns the value of @{b }stdrast@{ub } before setting it to the new value.  The
     following code fragments are equivalent:

            oldstdrast:=SetStdRast(newstdrast)
          
            oldstdrast:=stdrast
            stdrast:=newstdrast

@{b }SetTopaz(@{ub }@{fg shine }size@{fg text }@{b }=8)@{ub } 
     Sets the text font for the current raster port to Topaz at the
     specified size, which defaults to the standard size eight.


@ENDNODE

@NODE "Maths and logic functions" "Maths and logic functions"
@Next "System support functions" 
@Prev "Graphics functions" 
@Toc "Built-In Functions" 

Maths and logic functions
-------------------------

   We've already seen the standard arithmetic operators.  The addition, @{b }+@{ub },
and subtraction, @{b }-@{ub }, operators use full 32-bit integers, but, for
efficiency, multiplication, @{b }*@{ub }, and division, @{b }/@{ub }, use restricted values.
You can use @{b }*@{ub } only to multiply 16-bit integers, and the result will be a
32-bit integer.  Similarly, you can use @{b }/@{ub } only to divide a 32-bit integer
by a 16-bit integer, and the result will be a 16-bit integer.  The
restrictions do not affect most calculations, but if you really need to
use all 32-bit integers (and you can cope with overflows, etc.) you can
use the @{b }Mul@{ub } and @{b }Div@{ub } functions.  @{b }Mul(a,b)@{ub } corresponds to @{b }a*b@{ub }, and @{b }Div(a,b)@{ub }
corresponds to @{b }a/b@{ub }.

   We've also met the logic operators @{b }AND@{ub } and @{b }OR@{ub }, which we know are really
bit-wise operators.  You can also use the functions @{b }And@{ub } and @{b }Or@{ub } to do
exactly the same as @{b }AND@{ub } and @{b }OR@{ub } (respectively).  So, for instance, @{b }And(a,b)@{ub }
is the same as @{b }a AND b@{ub }.  The reason for these functions is because there
are @{b }Not@{ub } and @{b }Eor@{ub } (bit-wise) functions, too (and there aren't operators for
these).  @{b }Not(a)@{ub } swaps one and zero bits, so, for instance, @{b }Not(TRUE)@{ub } is
@{b }FALSE@{ub } and @{b }Not(FALSE)@{ub } is @{b }TRUE@{ub }.  @{b }Eor(a,b)@{ub } is the exclusive version of @{b }Or@{ub } and
does almost the same, except that @{b }Eor(1,1)@{ub } is 0 whereas @{b }Or(1,1)@{ub } is 1 (and
this extends to all the bits).  So, basically, @{b }Eor@{ub } tells you which bits
are different, or, logically, if the truth values are different.
Therefore, @{b }Eor(TRUE,TRUE)@{ub } is @{b }FALSE@{ub } and @{b }Eor(TRUE,FALSE)@{ub } is @{b }TRUE@{ub }.

   There's a collection of other functions related to maths, logic or
numbers in general:

@{b }Abs(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns the absolute value of @{fg shine }expression@{fg text }.  The absolute value of a
     number is that number without any minus sign (i.e., its the size of a
     number, disregarding its sign).  So, @{b }Abs(9)@{ub } is 9, and @{b }Abs(-9)@{ub } is also
     9.

@{b }Sign(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns the sign of @{fg shine }expression@{fg text }, which is the value one if it is
     (strictly) positive, -1 if it is (strictly) negative and zero if it
     is zero.

@{b }Even(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns @{b }TRUE@{ub } if @{fg shine }expression@{fg text } represents an even number, and @{b }FALSE@{ub }
     otherwise.  Obviously, a number is either odd or even!

@{b }Odd(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns @{b }TRUE@{ub } if @{fg shine }expression@{fg text } represents an odd number, and @{b }FALSE@{ub }
     otherwise.

@{b }Max(@{ub }@{fg shine }exp1@{fg text }@{b }, @{ub }@{fg shine }exp2@{fg text }@{b })@{ub } 
     Returns the maximum of @{fg shine }exp1@{fg text } and @{fg shine }exp2@{fg text }.

@{b }Min(@{ub }@{fg shine }exp1@{fg text }@{b }, @{ub }@{fg shine }exp2@{fg text }@{b })@{ub } 
     Returns the minimum of @{fg shine }exp1@{fg text } and @{fg shine }exp2@{fg text }.

@{b }Bounds(@{ub }@{fg shine }exp@{fg text }@{b }, @{ub }@{fg shine }minexp@{fg text }@{b }, @{ub }@{fg shine }maxexp@{fg text }@{b })@{ub } 
     Returns the value of @{fg shine }exp@{fg text } bounded to the limits @{fg shine }minexp@{fg text } (minimum
     bound) and @{fg shine }maxexp@{fg text } (maximum bound).  That is, if @{fg shine }exp@{fg text } lies between
     the bounds then @{fg shine }exp@{fg text } is returned, but if it is less than @{fg shine }minexp@{fg text }
     then @{fg shine }minexp@{fg text } is returned or if it is greater than @{fg shine }maxexp@{fg text } then
     @{fg shine }maxexp@{fg text } is returned.  This is useful for, say, constraining a
     calculated value to be a valid (integer) percentage (i.e., a value
     between zero and one hundred).

     The following code fragments are equivalent:

            y:=Bounds(x, min, max)
          
            y:=IF x<min THEN min ELSE IF x>max THEN max ELSE x

@{b }Mod(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } 
     Returns the 16-bit remainder (or modulus) of the division of the
     32-bit @{fg shine }exp1@{fg text } by the 16-bit @{fg shine }exp2@{fg text } as the regular return value (see
     @{"Multiple Return Values" Link "Procedures.guide/Multiple Return Values" }), and the 16-bit result of the division as the
     first optional return value.  For example, the first assignment in
     the following code sets @{b }a@{ub } to 5 (since 26=(7*3)+5), @{b }b@{ub } to 3, @{b }c@{ub } to -5
     and @{b }d@{ub } to -3.  It is important to notice that if @{fg shine }exp1@{fg text } is negative
     then the modulus will also be negative.  This is because of the way
     integer division works: it simply discards fractional parts rather
     rounding.

            a,b:=Mod(26,7)
            c,d:=Mod(-26,7)

@{b }Rnd(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns a random number in the range 0 to (n-1), where @{fg shine }expression@{fg text }
     represents the value n.  These numbers are pseudo-random, so although
     you appear to get a random value from each call, the sequence of
     numbers you get will probably be the same each time you run your
     program.  Before you use @{b }Rnd@{ub } for the first time in your program you
     should call it with a negative number.  This decides the starting
     point for the pseudo-random numbers.

@{b }RndQ(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns a random 32-bit value, based on the seed @{fg shine }expression@{fg text }.  This
     function is quicker than @{b }Rnd@{ub }, but returns values in the 32-bit range,
     not a specified range.  The seed value is used to select different
     sequences of pseudo-random numbers, and the first call to @{b }RndQ@{ub } should
     use a large value for the seed.

@{b }Shl(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } 
     Returns the value represented by @{fg shine }exp1@{fg text } shifted @{fg shine }exp2@{fg text } bits to the
     left.  For example, @{b }Shl(%0001110,2)@{ub } is @{b }%0111000@{ub } and @{b }Shl(%0001011,3)@{ub }
     is @{b }%1011000@{ub }.  Shifting a number one bit to the left is generally the
     same as multiplying it by two (although this isn't true when you
     shift large positive or large negative values).  (The new bits
     shifted in at the right are always zeroes.)

@{b }Shr(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } 
     Returns the value represented by @{fg shine }exp1@{fg text } shifted @{fg shine }exp2@{fg text } bits to the
     right.  For example, @{b }Shr(%0001110,2)@{ub } is @{b }%0000011@{ub } and @{b }Shr(%1011010,3)@{ub }
     is @{b }%0001011@{ub }.  For positive @{fg shine }exp1@{fg text }, shifting one bit to the right is
     the same as dividing by two.  (The new bits shifted in at the left
     are zeroes if @{fg shine }exp1@{fg text } is positive, and ones otherwise, hence
     preserving the @{fg shine }sign@{fg text } of the expression.)

@{b }Long(@{ub }@{fg shine }addr@{fg text }@{b }),  Int(@{ub }@{fg shine }addr@{fg text }@{b }),  Char(@{ub }@{fg shine }addr@{fg text }@{b })@{ub } 
     Returns the @{b }LONG@{ub }, @{b }INT@{ub } or @{b }CHAR@{ub } value at the address @{fg shine }addr@{fg text }.  These
     functions should be used only when setting up a pointer and
     dereferencing it in the normal way would make your program cluttered
     and less readable.  Use of functions like these is often called
     @{fg shine }peeking@{fg text } memory (especially in dialects of the BASIC language).

@{b }PutLong(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b }),  PutInt(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b }),  PutChar(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b })@{ub } 
     Writes the @{b }LONG@{ub }, @{b }INT@{ub } or @{b }CHAR@{ub } value represented by @{fg shine }exp@{fg text } to the
     address @{fg shine }addr@{fg text }.  Again, these functions should be used only when
     really necessary.  Use of functions like these is often called
     @{fg shine }poking@{fg text } memory.


@ENDNODE

@NODE "System support functions" "System support functions"
@Prev "Maths and logic functions" 
@Toc "Built-In Functions" 

System support functions
------------------------

@{b }New(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } 
     Returns a pointer to a newly allocated chunk of memory, which is
     @{fg shine }bytes@{fg text } number of bytes.  If the memory could not be allocated @{b }NIL@{ub } is
     returned.  The memory is initialised to zero in each byte, and taken
     from any available store (Fast or Chip memory, in that order of
     preference).  When you've finished with this memory you can use
     @{b }Dispose@{ub } to free it for use elsewhere in your program.  You don't have
     to @{b }Dispose@{ub } with memory you allocated with @{b }New@{ub } because your program
     will automatically free it when it terminates.  This is @{i }not@{ui } true for
     memory allocated using the normal Amiga system routines.

@{b }NewR(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } 
     The same as @{b }New@{ub } except that if the memory could not be allocated then
     the exception @{b }"MEM"@{ub } is raised (and so, in this case, the function
     does not return).  See @{"Exception Handling" Link "Exceptions.guide/main" }.

@{b }NewM(@{ub }@{fg shine }bytes@{fg text }@{b },@{ub }@{fg shine }type@{fg text }@{b })@{ub } 
     The same as @{b }NewR@{ub } except that the @{fg shine }type@{fg text } of memory (Fast or Chip) to
     be allocated can be specified using flags.  The flags are defined in
     the module @{b }exec/memory@{ub } (see @{"Amiga System Modules" Link "Modules.guide/Amiga System Modules" }).  See the `Rom
     Kernel Reference Manual (Libraries)' for details about the system
     function @{b }AllocMem@{ub } which uses these flags in the same way.

     As useful example, here's a small program which allocates some
     cleared (i.e., zeroed) Chip memory.

          MODULE 'exec/memory'
          
          PROC main()
            DEF m
            m:=NewM(20, MEMF_CHIP OR MEMF_CLEAR)
            WriteF('Allocation succeeded, m = $\\h\\n', m)
          EXCEPT
            IF exception="NEW" THEN WriteF('Failed\\n')
          ENDPROC

@{b }Dispose(@{ub }@{fg shine }address@{fg text }@{b })@{ub } 
     Used to free memory allocated with @{b }New@{ub }, @{b }NewR@{ub } or @{b }NewM@{ub }.  You should
     rarely need to use this function because the memory is automatically
     freed when the program terminates.

@{b }DisposeLink(@{ub }@{fg shine }complex@{fg text }@{b })@{ub } 
     Used to free the memory allocated with @{b }String@{ub } (see @{"String functions" Link "Types.guide/String functions" })
     or @{b }List@{ub } (see @{"List functions" Link "Types.guide/List functions" }).  Again, you should rarely need to use
     this function because the memory is automatically freed when the
     program terminates.

@{b }FastNew(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } 
     The same as @{b }NewR@{ub } except it uses a very fast, recycling method of
     allocating memory.  The memory allocated using @{b }FastNew@{ub } is, as ever,
     deallocated automatically at the end of a program, and can be
     deallocated before then using @{b }FastDispose@{ub }.  Note that only
     @{b }FastDispose@{ub } can be used and that it differs slightly from the
     @{b }Dispose@{ub } and @{b }DisposeLink@{ub } functions (you have to specify the number of
     bytes again when deallocating).

@{b }FastDispose(@{ub }@{fg shine }address@{fg text }@{b },@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } 
     Used to free the memory allocated using @{b }FastNew@{ub }.  The @{fg shine }bytes@{fg text }
     parameter must be the same as the @{fg shine }bytes@{fg text } used when the memory was
     allocated with @{b }FastNew@{ub }, but the benefit is much faster allocation and
     deallocation, and generally more efficient use of memory.

@{b }CleanUp(@{ub }@{fg shine }expression@{fg text }@{b }=0)@{ub } 
     Terminates the program at this point, and does the normal things an E
     program does when it finishes.  The value denoted by @{fg shine }expression@{fg text } is
     returned as the error code for the program.  It is the replacement
     for the AmigaDOS @{b }Exit@{ub } routine which should @{i }never@{ui } be used in an E
     program.  This is the only safe way of terminating a program, other
     than reaching the (logical) end of the @{b }main@{ub } procedure (which is by
     far the most common way!).

@{b }CtrlC()@{ub } 
     Returns @{b }TRUE@{ub } if control-C has been pressed since the last call, and
     @{b }FALSE@{ub } otherwise.  This is really sensible only for programs started
     from the Shell/CLI.

@{b }FreeStack()@{ub } 
     Returns the current amount of free stack space for the program.  Only
     complicated programs need worry about things like stack.  Recursion
     is the main thing that eats a lot of stack space (see @{"Recursion" Link "Recursion.guide/main" }).

@{b }KickVersion(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } 
     Returns @{b }TRUE@{ub } if your Kickstart revision is at least that given by
     @{fg shine }expression@{fg text }, and @{b }FALSE@{ub } otherwise.  For instance, @{b }KickVersion(37)@{ub }
     checks whether you're running with Kickstart version 37 or greater
     (i.e., AmigaDOS 2.04 and above).


@ENDNODE

