              _____          _________________________________
             /    /\        /                                 \
            /    / /       /    ___________________________    \
           /    / /       /    / _________________________/\    \
          /    / /       /    /_/___________      _____   \ \    \
         /    / /       /                   \    /\    \   \ \    \
        /    / /       /_________________    \   \ \    \   \ \    \
       /    / /        \________________/\    \   \ \    \   \ \    \
      /    /_/__________________________\_\    \   \ \    \___\/     \
     /                                          \   \ \              / 
    /____________________________________________\   \ \____________/
    \____________________________________________/    \/___________/FISH

                                P R E S E N T

                 AMIGA MACHINE LANGUAGE - FROM ABACUS BOOKS

                               P A R T  I I I


                     Typed by DEE JAY of X-CELL for LSD
                      Extra text by Pazza and Muridae



      Chapter 7.
      ----------
      7.Working With Intuition.
      -------------------------
        Now that you've learned so much about machine language,lets look
        at the special features of the Amiga.Lets look at the operating
        system Intuition that is in charge of windows,screens,the mouse
        and lots of other things.Beforetaking a look at these beautiful   
        features,theres some bad news.
        First,though,lets here the good news.Since Intuition has so many
        functions,it allows you to be very creative in programming your
        ideas.The disadvantage is that the flexibility means that you have
        to use a lot of parameters,and that makes for a lot of tedious
        work.
        However,this is no grounds for panic.Once you've built up the
        necessary routines,the programming and experimentation becomes
        increasingly interesting.Before you try out new program variations
        you should save your source code to disk,because Intuition gets
        fairly upset about bad parameters and often responds by crashing
        the system.
        Now lets get to work.To start working with Intuition,you need the 
        Intuition library.You can load it with the OpenLibrary function
        from the EXEC library.Heres the subroutine that takes care of
        initialization.

        openlib   =-408
        execbase  = 4

        run:
               bsr     openint         ;load intuition library
               ...

        openint:                       ;*initialize and open system
               move.l  execbase,a6     ;exec base address 
               lea     intname,a1      ;name of intuition library
               jsr     openlib(a6)     ;open intuition
               move.l  d0,intbase      ;save intuition base address
               rts

        intname: dc.b "intuition.library",0
               align
        intbase: dc.l 0                ;base address of intuition

        When your program is finished,you need to close the screens,the
        window and the library.To do this,use the CloseLibrary function
        from the EXEC library.It has an offset of -414.
        Heres the subroutine:

        closelibrary  =-414
               ...
        closeint:                        ;*close intuition
               move.l  execbase,a6       ;exec base address in A6
               move.l  intbase,a1        ;intuition base address in A1
               jsr     closelibrary(a6)  ;close intuition
               rts                       ;done

        Now that you've got that taken care of,you can finally start
        working with Intuition.

      7.1.Open Screen.
      ----------------
        Intuition is a graphics operating system.For this reason,you'll be
        working with the screen.Its even more interesting to work with
        several screens at the same time.However,you only have one monitor
        on the Amiga.
        You can open as many screens as you like (at least,as long as
        theres some memory available).You can open a window,display menus
        and do I/O's there.The individual screens are fully independant.
        You can work with all of them simultaneously on the monitor.
        You can move individual screens forward and back to your hearts
        content.You can also press the left <Amiga> key and then an "m"to
        return to the workbench screen after getting into the different
        screens.
        You want to begin programming Intuition by setting up a screen.You
        have already loaded the Intuition library,so you can use the Open-
        Screen function.
        Wait a minute!What should the screen look like,where should it go,
        and what form should it have?You need to look at the options for
        the form of the screen you have available.
        The input to the screen is in the form of a table that has 13
        entries.Lets take a look at the parameters that you need for our
        screen.
        You'll start the table with the label "screen_defs"which must be
        at an even address:

               align
        screen_defs:                 ;The screen table begins here

        The first bit of information that the screen needs is the position
        and size.Lets have it start in the upper left corner and fill the
        entire screen.You'll use the positions X=0 and Y=0,the width 320
        and the height 200.This means that your screen is the maximum
        size.

        x_pos:     dc.w   0        ;X-Position
        y_pos:     dc.w   0        ;Y-Position
        width:     dc.w   320      ;width
        height:    dc.w   200      ;height

        Next you need to decide which colors should be displayed.That
        depends on the number of bitplanes,on the depth.Lets choose two.  
        That means you have 2^2 (4) colours available.Lets choose two,
        since four colours is usually plenty.

        depth:     dc.w   2        ;number of bitplanes

        Next you need to choose the colour of the title line and the
        function symbols.Give the number of the colour register:

        detail_pen:  dc.b   0      ;colour of text,etc...

        Now for the colour of the text background:

        block_pen    dc.b   1      ;background colour

        Make sure that these two inputs fit in a byte.The colours are
        normally the following (if the standard values have'nt been
        changed).You'll notice that the number of colours depends on the
        number of bit maps.

            Pen        Colour
         ---------------------------------------------------------
             0         Background (blue)
             1         White
          for two bit planes
             2         Black
             3         Red
          for three bit planes
             4         Blue
             5         Violet
             6         Turquoise
             7         White
          for four bit planes
             8         Black
             9         Red
            10         Green
            11         Brown
            12         Blue
            13         Blue
            14         Green
            15         Green

        The next word contains the bits that describe the appearance of
        the screen.The bits are:

        Bit    Value    Name             Meaning
        ---------------------------------------------------------------  
         1       2      GENLOCK_VIDEO    
         2       4      INTERLACE        Puts the screen in Interlace
                                         mode.The resolution and thus the 
                                         maximum screen size are doubled.
         6     $40      PFBA
         7     $80      EXTRA_HALFBRITE
         8     $100     GENLOCL_AUDIO
        10     $400     DBLPF            Divides the screen into a border
        and                              character area.
        11     $800     HOLDNMODIFY      Turns on Hold-and-Modify mode.
        13     $2000    VP_HIDE
        14     $4000    SPRITES          Allows sprites to be used.
        15     $8000    MODE_640         Turns on the highest resolution  
                                         graphics for the screen(640x400).

        Choose the value two (normal) for your example screen:

        view_modes:  dc.w   2         ;representation mode

        The following word is constructed in such away that each bit as
        its own meaning.Use this to set what sort of screen it is.Choose
        15 so the screen is a "Custom screen",which allows you all of the 
        options.

        screen_type:  dc.w  15      ;screen type:custom screen

        Next theres a pointer to the character set to be used for all
        output to the screen.If you don't want to install your own
        character set,just put a zero here,and the standard character set 
        is used.

        font:   dc.l  0         ;character set:standard

        Next theres a pointer to the text thats used as the name of the
        screen.The text ends with a zero,just like window names must. 

        title:  dc.l  name      ;pointer to title text

        Next comes a long word that defines the gadgets.These gadgets
        represent the functions,like "Bring forward",that can be accessed 
        via a mouse click in the screen.The long word in this table is a
        pointer to a list which specifies the gadgets.These aren't the
        system gadgets.However,you're only using system gadgets here,so
        put a zero here.

        gadgets:  dc.l  0        ;no gadgets

        Finally theres a long word that you only need if you want to use
        the special bitmap just for your screen.Since this isn't the case,
        just put a zero here.

        bitmap:  dc.l  0         ;no bitmap

        Thats it for the list entries that you need to define the screen. 
        You still need the text for the name of the screen.Enter the
        following:

        sname:   dc.b  'Our Screen',0    ;screen title

        Heres a quick overview of the list:

               align
        screen_defs:                  ;*The screen ta
        x_pos:        dc.w  0         ;X-position
        y_pos:        dc.w  0         ;Y-position
        width:        dc.w  320       ;width
        height:       dc.w  200       ;height
        depth:        dc.w  2         ;number of bitplanes
        detail_pen:   dc.b  0         ;colour of the text,etc...
        block_pen:    dc.b  1         ;background colour
        view_modes:   dc.w  2         ;representation mode
        screen_type:  dc.w  15        ;screen type:custom screen
        font:         dc.l  0         ;character set:standard
        title:        dc.l  sname     ;pointer to title text
        gadgets:      dc.l  0         ;no gadgets
        bitmap:       dc.l  0         ;no bit map
        sname:        dc.b  'Our Screen',0  ;screen title

        Once you've decided on the parameters,its very easy to open the
        screen.You need Intuitions OpenScreen function.Its offset is -198 
        and it only needs one parameter,the address of the parameter
        table.The program fragment looks like this:

        openscreen =-198
               bsr     openint            ;open intuition
               bsr     scropen            ;open screen
               ...
        scropen:                          ;*open screen
               move.l  intbase,a6         ;intuition base address in A6
               lea     screen_defs,a0     ;pointer to table
               jsr     openscreen(a6)     ;and open
               move.l  d0,screenhd        ;save screen handle
               rts                        ;return to main program
               ...
        screen_defs:                      ;table info follows

        Now the Amigas Workbench screen is covered by your screen.Now you 
        can do what you want with it until the program is done.Afterwards,
        the screen must be closed again,so that you can see the Workbench 
        screen again.
        Use the CloseScreen function (offset -66) to do this.The only
        parameter it needs is the pointer to the screen structure you got 
        back from the OpenScreen function.

        closescreen =-66
               ...
        scrclose:                         ;* close screen
               move.l  intbase,a6         ;intuition base address in A6
               move.l  screenhd,a0        ;screen handle in A0
               jsr     closescreen(a6)    ;clos screen
               rts                        ;done

        The long word that OpenScreen returned to you is a pointer to a
        screen structure that contains all the needed data about the
        screen.Besides the data which was given,there is a pointer in the 
        screen area for individual bit planes,etc...
        The form of this structure is fairly complicated and contains some
        data that you can't use.Several of the parameters are interesting,
        however.Heres a selection of usable parameters:

        No    Name              Function
        ------------------------------------------------------------------
        0     (NextScreen.L)    Pointer to next screen.
        4     (FirstWindow)     Pointer to first window structure
        8     (LeftEdge.W)      
        $A    (TopEdge.W)       Position of screen
        $C    (Width.W)         Width
        $E    (Height.W)        Height
        $10   (MouseY.W)
        $12   (MouseX.W)        Mouse position in the screen
        $14   (Flags.W)         Screen flags
        $16   (Title.L)         Pointer to title text
        $1A   (DefaultTitle)    Pointer to normal title
        $28   (Font.L)          Pointer to character set
        $C0   (Plane0.L)        Pointer to bitplane 0
        $C4   (Plane1.L)        Pointer to bitplane 1
        $C8   (Plane2.L)        Pointer to bitplane 2
        $CC   (Plane3.L)        Pointer to bitplane 3

        An example of an application for the plane pointer is writing and 
        using your own character routine.Next you want to move the address
        of the plane into an address register as follows:

               move.l  screenhd,a5        ;screen pointer in A5
               move.l  $c0(a5),a5         ;bitplane 0-pointer in A5

        If you want to try this,do the following:

               move.l  screenhd,a5        ;screen pointer in A5
               move.l  $c0(a5),a5         ;bitplane 0-pointer in A5
               move    #$20,d0            ;Counter D0=$20

        lop1:
               move    d0,(a5)            ;write counter bits in picture
               add.l   #80,a5             ;address+80,next line
               dbra    d0,lop1            ;continue until D0 < 0

        This program draws a white,square pattern that corresponds to the 
        bit pattern for the numbers $20 to 0.This isn't a particularly
        useful program,but it shows how easy it is to write from a machine
        language program directly to the screen.If you change the offset
        in the second line to $C4,the pattern is read.
        You can move the entire screen with the normal technique of moving
        the mouse pointer into the upper border and moving it up and down 
        with the left mouse key depressed.You can do the same with a
        program.
        Lets move the screen without the mouse.Use the joystick for
        demonstration purposes.Put the joystick in port two.As you saw in
        the chapter on the hardware register,you can read memory location 
        $DFF00C to find information about the joystick.You can find the
        direction the screen should be moved here.
        Moving the screen requires another Intuition function.You use the 
        MoveScreen function which as an offset of -162 and needs three
        parameters to do this.The parameters are:

        In A0   the pointer to the screen structure that you got back in
                D0 when you opened the screen.(You saved it in "screenhd")
        In D1   the desired movement in the Y-direction,the vertical
                direction.
        In D0   the horizontal movement in the X-direction.The varient
                doesn't work so you can only move the screen vertically.

        Insert the following lines in your program:

        MoveScreen =-162
               ...
        scrmove:                          ;*move screen D0 to the right
                                          ;and D1 down
               move.l  intbase,a6         ;intuition base address in A6
               move.l  screenhd,a0        ;screen handle in A0
               clr.l   d0                 ;no horizontal movement
               jsr     movescreen(a6)     ;move screen
               rts                        ;done

        Now your looking at a complete program that goes through the
        following steps:

        1.  Opens the Intuition library
        2.  Opens the screen
        3.  Moves the screen in the direction specified by the joystick in
            port two
        4.  Closes the screen when the fire button is hit
        5.  Closes the Intuition library
        6.  Ends

        Here is the complete program including the subroutines,so you'll
        have it all in one spot:

        ;** Demo program to open and move a screen **

        movescreen   =-162
        openscreen   =-198
        closescreen  =-66
        closelibrary =-414
        openlib      =-408                ;open library
        execbase     = 4                  ;exec base address
        joy2         =$dff00c             ;joystick 2 data
        fire         =$bfe001             ;firebutton 2:bit 7

        run:
               bsr     openint            ;open intuition
               bsr     scropen            ;open screen
               move    joy2,d6            ;save joystick info

        loop:
               tst.b   fire               ;test fire button
               bpl     ende               ;pressed down:done
               move    joy2,d0            ;basic info in D0
               sub     d6,d0              ;subtract new data
               cmp     #$0100,d0          ;up?
               bne     noup               ;no
               move.l  #-1,d1             ;dy=-1 direction y
               bsr     scrmove            ;move up
               bra     loop

        noup:
               cmp     #$0001,d0          ;down?
               bne     loop               ;no
               move.l  #1,d1              ;dy=1
               bsr     scrmove            ;move down
               bra     loop

        ende:
               bsr     scrclose           ;close screen
               bsr     closeint           ;close intuition
               rts                        ;done!

        openint:                          ;*initialize and open system
               move.l  execbase,a6        ;exec base address
               lea     intname,a1         ;name of intuition library
               jsr     openlib(a6)        ;open intuition
               move.l  d0,intbase         ;save intuition base address
               rts

        closeint:                         ;*close intuition
               move.l  execbase,a6        ;exec base address in A6
               move.l  intbase,a1         ;intuition base address in A1
               jsr     closelibrary(a6)   ;close intuition
               rts                        ;done

        scropen:                          ;*open screen
               move.l  intbase,a6         ;intuition base address in A6
               lea     screen_defs,a0     ;pointer to table
               jsr     openscreen(a6)     ;open
               move.l  d0,screenhd        ;save screen handle
               rts                        ;return to main program

        scrclose:                         ;*close screen
               move.l  intbase,a6         ;intuition base address in A6
               move.l  screenhd,a0        ;screen handle in A0
               jsr     closescreen(a6)    ;close screen
               rts                        ;done

        scrmove:                          ;move screen D0 right/D1 down
               move.l  intbase,a6         ;intuition base address in A6
               move.l  screenhd,a0        ;screen handle in A0
               clr.l   d0                 ;no horizontal movement
               jsr     movescreen(a6)     ;and move
               rts                        ;done
               align

        screen_defs:                      ;*screen table begins here
        x_pos:         dc.w  0            ;X-position
        y_pos:         dc.w  0            ;Y-position
        width:         dc.w  320          ;width
        height:        dc.w  200          ;height
        depth:         dc.w  2            ;number of bitplanes
        detail_pen:    dc.b  1            ;Text colour=white
        block_pen:     dc.b  3            ;background colour=red
        view_modes:    dc.w  2            ;representation mode
        screen_type    dc.w  15           ;screen type:custom screen
        font:          dc.l  0            ;standard character set
        title:         dc.l  sname        ;pointer to title text
        gadgets:       dc.l  0            ;no gadgets
        bitmap:        dc.l  0            ;no bit map
        intbase:       dc.l  0            ;base address of intuition
        screenhd:      dc.l  0            ;screen handle
        intname:       dc.b  'intuition.library',0
               align
        sname:         dc.b  'Our Screen',0   ;Screen title
               align
               end

        From this example,you can see how easy scrolling actually is.     
        Another easy thing to do is to use the DisplayBeep function.It as 
        an offset -96;the only parameter it needs is the screen pointer
        that you stored in the "screenhd"memory block.This function covers
        the screen with an orange colour for a short while.The screen is  
        not changed.The beep function can be used as follows:

        DisplayBeep: =-96
               ...
               move.l  intbase,a6         ;intuition base address in A6
               move.l  screenhd,a0        ;screen pointer in A0
               jsr     displaybeep(a6)    ;light up screen

        If you put a zero instead of a screen pointer in A0,the whole
        screen blinks.
        Good,now you have your own screen that you can move up and down.  
        What good is it if you can't put anything on it?Lets open a window
        on the screen!

      7.2.Open Window.
      ----------------
        As you saw in the chapter on program initialization,its easy to
        open a window with the DOS library.You can't use this method on
        your own screen however.You need to use another method that can
        open any window on any screen.
        Intuition has a function called OpenWindow which handles this sort
        of work.It has an offset of -204 and needs only one parameter,a
        pointer to a window definition table.This pointer goes in register
        A0.
        This table is very similar to the one used to define the screen.  
        The first four values specify the X-and Y-positions,the width,and
        the height of the window to be opened.Heres an example:

               align
        window_defs:
                       dc.w  10           ;x-position
                       dc.w  20           ;y-position
                       dc.w  300          ;width
                       dc.w  150          ;height

        Next come two bytes that define the colour of the letters on the  
        background:

                       dc.b  1            ;white letter colour
                       dc.b  3            ;on a red background

        The next long word contains the IDCMP flags in its bits.The bits  
        determine the circumstances under which Intuition sends a message 
        to the program.The bits have the following meanings:

        Bit  Value     Name             Meaning
        -----------------------------------------------------------------
         0   $000001   SIZEVERIFY
         1   $000002   NEWSIZE          Window size changed
         2   $000004   REFRESHWINDOW
         3   $000008   MOUSEBUTTONS     Mouse key hit
         4   $000010   MOUSEMOVE        Mouse moved
         5   $000020   GADGETDOWN       A special gadget chosen
         6   $000040   GADGETUP         Same as above
         7   $000080   REQSET
         8   $000100   MENUPICK         A menu item chosen
         9   $000200   CLOSEWINDOW      A window closed
        10   $000400   RAWKEY           A key pressed
        11   $000800   REQVERIFY
        12   $001000   REQCLEAR
        13   $002000   MENUVERIFY
        14   $004000   NEWPREFS         Preferences modified
        15   $008000   DISKINSERTED     A disk put in
        16   $010000   DISKREMOVED      A disk taken out
        17   $020000   WBENCHMESSAGE
        18   $040000   ACTIVEWINDOW     A window activated
        19   $080000   INACTIVEWINDOW   A window deactivated
        20   $100000   DELTAMOVE        Report relative mouse movement

        If you want your first window to respond only by clicking on the
        close symbol,write the following:

            dc.l  $200   ;IDCMP flags:CLOSEWINDOW

        Next comes a long word whose bits determine the windows type.You  
        can use this to construct a window to your exact specifications.  
        This is quite different from windows opened with the DOS function.
        The bits mean:

        Bit  Value     Name             Meaning
        ------------------------------------------------------------------
         0   $0000001  WINDOWSIZING     Window size is changeable
         1   $0000002  WINDOWDRAG       Window is moveable
         2   $0000004  WINDOWDEPTH      Window covering is posible
         3   $0000008  WINDOWCLOSE      Window close symbol
         4   $0000010  SIZEBRIGHT
         5   $0000020  SIZEBOTTOM
         6   $0000040  SIMPLE_REFRESH   New drawing manuel
         7   $0000080  SUPER_BITMAP     Save the windows contents
         8   $0000100  BACKDROP         Move window back
         9   $0000200  REPORTMOUSE      Report mouse co-ordinates
        10   $0000400  GIMMEZEROZERO
        11   $0000800  BORDERLESS       Window without border
        12   $0001000  ACTIVATE         Window active
        13   $0002000  WINDOWACTIVATE
        14   $0004000  INREQUEST
        15   $0008000  MENUSTATE
        16   $0010000  RMBTRAP          Right mouse key:no menu
        17   $0020000  NOCAREREFRESH    No refresh message
        24   $1000000  WINDOWREFRESH
        25   $2000000  WBENCHWINDOW

        To refresh is to rebuild the window contents when necessary,for
        instance when the windows size is changed.If none of the refresh
        bits are set,you're in Smart-Refresh-Mode.In this case,Intuition
        takes care of refreshing the window.This is the easiest method.
        If you choose the value $100F as the type for your example window,
        the window is active once its opened,and it has all the system
        gadgets:

             dc.l   $100F       ;ACTIVATE and all gadgets

        The next long word in the list allows you to use your own gadgets
        in the window.This long word is a pointer to the structure of a
        your gadget.Since you don't want this,just put a zero here.

             dc.l   0           ;first gadget:no gadgets of our own

        The next long word is a pointer to a graphics structure so you can
        design your own symbol for checking menu points.Put a zero here.
        You'll use the standard sign:

             dc.l   windowname  ;pointer to window name

        The next long word is a pointer to the screen structure that you
        got back after calling the OpenScreen function.The easiest way to
        do this is to save the pointer to this location in the buffer:

        screenhd:   dc.l 0   ;screen pointer

        The next long word is a pointer to a bit map if you want one of
        your own for the window.Since you don't want one,put a zero here.

                dc.l  0        ;no bit map of our own

        Next come four values that set the maximum and minimum width and  
        height of the window:

                dc.w  150      ;smallest width
                dc.w  50       ;smallest height
                dc.w  320      ;maximum width
                dc.w  200      ;maximum height

        The last value in the list is the screen type of the screen the
        window is located in.Put a 15 here.You're using our screen as a   
        custom screen:

                dc.w  15       ;screen type:custom screen

        Heres a quick overview of the whole list:

            align
        window_prefs:
                      dc.w   10           ;X-position
                      dc.w   20           ;Y-position
                      dc.w   300          ;width
                      dc.w   150          ;height
                      dc.b   1            ;white print colour
                      dc.b   3            ;on red background
                      dc.l   $200         ;IDCMP flags:CLOSEWINDOW
                      dc.l   $100f        ;ACTIVATE and all gadgets
                      dc.l   0            ;first gadget:no gadgets of
                                          ;our own
                      dc.l   0            ;checkmark:standard
                      dc.l   windowname   ;pointer to window name
        screenhd:     dc.l   0            ;screen pointer
                      dc.l   0            ;no bitmap of our own
                      dc.w   150          ;smallest width
                      dc.w   50           ;smallest height
                      dc.w   320          ;maximum width
                      dc.w   200          ;maximum height
                      dc.w   15           ;screen type:custom screen
 
        ;and here comes the window name:
        windowname:   dc.b   'Our Window',0
            align

        Insert these lines in the program you listed above.Here are two   
        subroutines for opening and closing the window:

        openwindow  =-204
        closewindow =-72
               ...
        windopen:
               move.l  intbase,a6        ;intuition base address in A6
               lea     windowdef,a0      ;pointer to window definition
               jsr     openwindow(a6)    ;open window
               move.l  d0,windowhd       ;save window handle
               rts

        windclose:
               move.l  intbase,a6        ;intuition base address in A6
               move.l  windowhd,a0       ;window handle
               jsr     closewindow(a6)   ;close window
               rts
               ...
        windowhd:      dc.l   0          ;window handle

        Now you can insert a "bsr windowopen"after the "bsr scropen"and a 
        "bsr windclose"before the "bsr scrclose"command.Once you've
        started the program,move the window around in the screen.You'll
        find that you can't move the window out of the screen with the
        mouse. 
        The window in the example has the close gadget in the upper left
        corner.Normally if you click it,the window is closed.Try clicking
        it.You'll find that nothing happens.
        The display of this and all other gadgets,as well as other events
        must be programmed in,since Intuition doesn't know which action
        causes which event.We'll take a look at how to handle this in the 
        next chapter.

      7.3.Requesters.
      ---------------
        If you only have one disk drive,you've certainly seen the Amiga   
        message,"Please insert xxx in unit 0",a lot.This window is another
        that has two fields for clicking.This sort of message with a
        choice of options is called a requester.                          
        You want to take a look at how to program a requester.First,you
        need a window for the requester to appear in.You opened a window
        of this sort in the example program.
        To display a requester,use the Intuition function AutoRequest
        (offset -348).It takes care of drawing and managing the requester.
        This function needs the following parameters:

        In A0   The pointer to the window structure that you put in
                "windowhd".
        In A1   A pointer to the text structure that should stand over the 
                choice buttons.
        In A2   Same as above for the text of the left button.
        In A3   Same as above for the right button.
        In D0   The IDCMP flag which lets you know what event should go
                with the clicking of the left button.
        In D1   Same as above for the right button.
        In D2   The width of the whole requester.
        In D3   The height of the requester.

        Insert the following lines in your program:

        autorequest =-348
               ...
        request:
               move.l  windowhd,a0       ;pointer to window structure
               lea     btext,a1          
               lea     ltext,a2          ;pointer to text structure
               lea     rtext,a3        
               move.l  #0,d0             ;left activates by clicking
               move.l  #0,d1             ;right activates by clicking
               move.l  #180,d2           ;width and
               move.l  #80,d3            ;height of requester
               move.l  intbase,a6        ;intuition base address
               jsr     autorequest(a6)   ;display requester
               rts

        The flags passed in D0 and D1 offer some interesting posibilites. 
        The system messages that tells you to enter a particular disk are 
        overlooked when the DISKINSERTED flag is similar.Putting a disk in
        brings about the same responce as clicking the "Retry"button.
        Whats new is the use of a text structure.Use three of them.Text   
        structures are lists that contain entries for the text that you
        need. 
        These lists begin with two bytes that are used to define the
        colour.The first byte is the colour of the text.The second is for
        the background colour.Here this doesn't have any meaning.

        btext:
               dc.b    2                 ;black text colour
               dc.b    0                 ;background colour

        The next byte specifies the character mode.A zero means that the
        text is output normally.A four means the text is output inverted.

               dc.b    0                 ;normal text representation

        The next entries are words.For this reason the addresses must be
        even,so you need to either insert another byte or use the "align" 
        pseudo-op.The following words are the X-and Y-position of the text
        relative to the upper left corner of the requester.

               dc.w    10                ;X-position
               dc.w    5                 ;Y-position relative to upper
                                         ;left corner

        Next,theres a pointer to the character set that is used.Put a zero
        here to use the standard set.

               dc.l    0                 ;standard character set

        Next you need to give the address of the text that should be
        output.This text must be closed with a null byte.

               dc.l    text              ;pointer to text

        You need a long word at the end of the list that is either a
        pointer to another text or a zero if no more text is needed.

               dc.l    0                 ;no more text

        Here are the three text structures that you need for the example:

        btext:                           ;text structure for the title
               dc.b    0,1               ;colour
               dc.b    0                 ;mode
               align
               dc.w    10,10             ;text position
               dc.l    0                 ;standard font
               dc.l    bodytxt           ;pointer to text
               dc.l    0                 ;no more text

        bodytxt:
               dc.b    "Requester Text",0
               align
        ltext:                           ;text structure of left button
               dc.b    0,1               ;colour
               dc.b    0                 ;mode
               align 
               dc.w    5,3               ;text position
               dc.l    0                 ;standard font
               dc.l    lefttext          ;pointer to text
               dc.l    0                 ;no more text

        lefttext:
               dc.b    "left",0
               align

        rtext:
               dc.b    0,1               ;colour
               dc.b    0                 ;mode
               align
               dc.w    5,3               ;text position
               dc.l    0                 ;standard font
               dc.l    righttext         ;pointer to text
               dc.l    0                 ;no more text

        righttext:
               dc.b    "right",0
               align

        After calling the requester,D0 contains the information about
        which of the buttons were pressed,and in which button the event
        took place.If D0 is zero,it was the right button.If it is one,it
        was the left button.

      7.4.Event Handling.
      -------------------
        Pretend you've opened a window that as a close symbol,and you want
        the program to react to this symbol being clicked.You need a
        signal from Intuition that lets you know that an event as taken
        place.The signal is called a message.
        The IDCMP flag of the window specifies which events should cause
        Intuition to send a message.By setting the bits for WINDOWCLOSE,  
        you can allow a message to be sent when the close symbol is
        clicked.
        To get the message,you can use the EXEC function GetMsg (offset
        -372).It needs the source address of the event as a parameter.Here
        the source is the User port (which doesn't have anything to do
        with the User port on old Commodore computors).
        The User port contains a table which has entrieswhich specify the
        events that have taken place and related things like mouse
        position and time.
        How do you find the User port?Use the pointer to the window
        structure that you got back from the OpenWindow function and
        stored in the "windowhd"memory block.
        This pointer points to the window structure of this window.This
        structure consists of a number of entries.Some are copies of the
        parameters from our window definition table.We won't cover all the
        entries,because most won't be interesting to you.You're more
        interested in the pointer to the User port.Its in the window
        structure.
        You can find this in the long word that begins in the 86th byte of
        the structure.You can get this long word with the following lines
        of code:

               move.l  windowhd,a0       ;pointer to structure in A0
               move.l  86(a0),a0         ;user port pointer in A0

        You can call the GetMsg function with this pointer in A0 by using 
        the following lines of code in your program:

        GetMsg  = -372
               ...
               move.l  windowhd,a0       ;pointer to structure in A0
               move.l  86(a0),a0         ;user port pointer in A0
               move.l  execbase,a6       ;exec base address in A6
               jsr     getmsg(a6)        ;get message

        This function returns a value in the D0 register.This value is a  
        pointer to another structure,the Intuition Message Structure.If
        theres a zero in D0,no event as taken place.
        The long word that starts at the 20th byte in this structure
        contains the information about which event took place.Evaluating
        the information is easy,since the bits of this long word have the 
        same meaning as the IDCMP flag that you described when you looked 
        at opening windows.
        Put the lines above after "loop"and then insert the following:

               move.l  d0,a0             ;message pointer in A0
               move.l  20(a0),d6         ;save event in D6
               tst.l   d0                ;did the event take place?
               bne     end               ;yes!

        Now you can end this program by clicking the close symbol.This way
        you can find out if an event as taken place.You can use D6 to
        determine what event took place.In the example,D6 contains the
        number $00000200,which means that the close symbol was clicked.
        To see if this works with other events,change the $200 IDCMP flag
        to $10200 in the window definition table.When you've assembled and
        started this version,take the disk out of the drive-the program
        terminates.
        The IDCMP flags that you've got now cause the clicking of the
        close symbol and the taking out of the disk (DISKREMOVED) to be
        reported.If you want to find out which of the events took place,  
        you can look in D6.It has a $200 in it if the window is closed,a  
        $10000 if the disk was removed.

      7.5.Menu Programming.
      ---------------------
        Now lets look at one of Intuitions more interesting capabillities:
        menu programming.By using menus,you can make your programs very
        user friendly.
        There are a lot of ways for you to use menus.You can make menu
        points unusable,output sub-menus,choose the type of menu entries  
        (allow text or pictures to be output),etc..To have lots of options
        you need some parameters.
        Lets produce a menu with the SetMenuStrip function (offset -264)
        of Intuition.The function only needs two parameters,a pointer to
        the menu structure of the window to be drawn and a pointer to the 
        window structure of the window in which the menu is to function.  
        Each window can have its own menu that is active when the window
        is activated.
        Heres the subroutine to set up the menu:

        SetMenuStrip =-264
               ...
        setmenu:                         ;* Initialize a menu
               move.l  intbase,a6        ;intuition base address in A6
               move.l  windowhd,a0       ;pointer to window structure
               lea     menu,a1           ;pointer to menu structure
               jsr     setmenustrip(a6)  ;call function
               rts

        Heres a routine to erase the menu:

        ClearMenuStrip =-54
               ...
        clearmenu:
               move.l  intbase,a6        ;intuition base address in A6
               move.l  windowhd,a0       ;pointer to window structure
               jsr     clearmenustrip(a6)
               rts

        You've already got the pointer to the window structure.Lets look
        at the menu structure you need for the menu.You need to build a
        structure like this for each menu--for each menu title that
        appears when you press the right mouse key.
        This structure is a table with the following form:

        First there is a long word that points to the menu structure of
        the next menu.If the current menu is the last one,a zero goes
        here.

               align
        menu:
               dc.l    menu1             ;pointer to the next menu

        Next come two words which contain tha X- and Y-position of the
        menu title:

               dc.w    20                ;X-position
               dc.w    0                 ;Y-position

        Next,use two words to store the menu titles width and height in
        pixels:

               dc.w    50                ;width
               dc.w    10                ;height of menu title

        The next word contains the flag bit that determines whether the
        menu is available or not.An unavailable menu either as grey
        entries or they are drawn weakly.If the flag bit,bit 0,is set the 
        menu is available.Otherwise,it is not.

               dc.w    1                 ;menu available

        Now comes a long word which functions as a pointer to the text
        which is used as the menu title.Make sure the length isn't larger 
        than the width entry allows!Otherwise unpleasent things will
        happen.

               dc.l    menutext          ;pointer to title text

        Next comes a long word which functions as a pointer to the
        structure of the first menu entry of this menu.Each menu entry
        needs its own structure. 

               dc.l    menuitem01        ;pointer to the first menu item

        The last entries in the table are four words that are reserved for
        internal functions.They must be here.

               dc.w    0,0,0,0           ;reserved words

        Thats the structure of the first menu.This structures first long
        word points to the next structure which has the same form.The
        pointer is set to zero in the last menu.
        You still need the structure of the menu entries.These structure
        tables have the following form:

        They start with a pointer to the next menu item.This pointer is
        set to zero for the last entry.

               align
        menuitem01:
               dc.l    menuitem02        ;pointer to next menu item

        Next comes the four words:the X- and Y-position,the width and the 
        height of the box the menu entry goes in.The size becomes obvious 
        when the item is chosen by having the right mouse key clicked on
        it.Then the box becomes visible.As you can see,the next word is   
        determined in the flags.First lets set the position and size of
        the menu point,though:

               dc.w    0                 ;X-position of entry
               dc.w    0                 ;Y-position
               dc.w    90                ;width in pixels
               dc.w    10                ;height in pixels

        The position entries are relative to the upper left corner of the 
        menu that is pulled down.
        The following word was described above:it contains flags for
        entries to this menu item.There are several interesting variations
        possible.The following flag bits are contained in this word:

        Bit   Value   Name          Meaning When Set
        ------------------------------------------------------------------
         0    $0001   CHECKIT       Point is checked when chosen
         1    $0002   ITEMTEXT      Text menu item
         2    $0004   COMMSEQ       Choice can be made with keys as well
         3    $0008   MENUTOGGLE    Check turned on and off
         4    $0010   ITEMENABLED   Menu item available
         6    $0040   HIGHCOMP      Item inverted when chosen
         7    $0080   HIGHBOX       Iten framed when chosen
         8    $0100   CHECKED       Item is checked

        Heres a description of the bits:

        Name           Description
        ------------------------------------------------------------------
        CHECKIT        If this bit is set,a check or a user-defined
                       drawing is put in front of the text when the item  
                       is chosen.The text should begin with two blanks.
        
        ITEMTEXT       The menu item is a normal text if this bit is set. 
                       Otherwise a drawing is output.

        COMMSEQ        By setting this bit and entering a character,this  
                       menu point can be chosen by pressing the right
                       <Amiga> key and the key that was input.The input   
                       character is then displayed in the menu with the
                       Amiga symbol.There needs to be space available for 
                       this.

        MENUTOGGLE     If this bit is set and checking is allowed (bit 0),
                       the second time this point is chosen the check is
                       erased,the next time it is displayed again,etc...

        ITEMENABLED    Erasing this bit makes the menu item available.

        HIGHCOMP       If this bit is set,the box you've defined is
                       inverted when this menu item is chosen by the mouse
                       pointer.

        HIGHBOX        In this mode,the box is framed whin its chosen.

        The two previous bits determine the mode of the chosen menu item. 
        The following combinations are possible:

        HIGHIMAGE      If both bits are cleared,choosing the bit causes a 
                       self-defined drawing to be output.

        HIGHNONE       When both bits are set,there isn't any reaction to 
                       choosing this item.

        CHECKED        This bit can be set by either the program or
                       Intuition.It lets you know if the menu text has a
                       check next to it or not.You can use this to find
                       out if the item was checked by testing but eight.If
                       its set,the item was checked.You can also use it to
                       cause the item to be checked.

        You're choosing the mode CHECKIT,ITEMTEXT,COMMSEQ,MENUTOGGLE,ITEM-
        ENABLED and HIGHBOX for the example:

              dc.w    $10011111         ;mode flag

        Lets get back to the structure of the menu items.After the flag
        word,there is a long word whose flag bits determine whether this  
        menu point can be turn off another one.Set this to zero:

              dc.l    0                 ;no connection

        Now comes the pointer to the structure of the text that should be 
        displayed.If the ITEMTEXT bit isn't set,this pointer must point to
        the structure of the drawing.If nothing should be shown,you can
        set this to zero.Use a text in the example and write the
        following:

              dc.l    menu01text        ;pointer to menu text structure

        The following long word only has a meaning if the HIGHIMAGE flag
        is set.Then this long word points to the text or the drawing that 
        should be displayed when the menu items box is clicked.Otherwise  
        the long word is ignored,so insert a zero:

              dc.l    0                 ;no drawing when clicked

        The next entry is a byte that is used for input of keyboard
        characters,which together with the right <Amiga> key can be used
        to choose the menu item.This only works if the COMMSEQ bit is set.
        Place a character here:

              dc.b    'A'               ;choose item using <Amiga>/'A'

        Since the next item is a long word,you need an "align"peudo-op
        here.Next comes the long word that points to the menu item
        structure or a submenu.The submenu is automatically shown when
        this menu item is clicked.You can't nest them any deeper,however, 
        so this long word is ignored for submenus.
        If you don't want a submenu to this item,put a zero here:

          align
              dc.l    0                 ;no submenu

        The next and final long word is written to by Intuition if you
        choose several menu itens.In this case,the menu number of the next
        menu item chosen goes here:

              dc.l    0                 ;preparation

        Thats the structure for a menu item.You still need the text
        structure for the text of the item.This isn't complicated,but it
        makes you get into fine details about the form of the menu.You've 
        already learned about this text structure when you looked at
        requesters,so we'll skip an explanation.
        Heres the complete structure of an example menu.You can use two
        menus,each with two subpoints.The second menu point of the left
        menu has a submenu with two entries.You ought to type this program
        in,so that you can experiment with it.You can also use this
        example to evaluate the clicked menu item.

        ;**Complete menu structure foe example menu **
        menu:
               dc.l menu1         ;no next menu
               dc.w 10,30         ;X/Y
               dc.w 50,10         ;width/height
               dc.w 1             ;menu enabled
               dc.l menuname      ;menu title
               dc.l menuitem01    ;menu entry
        menuname:
               dc.b "Menu 1",0    ;first menu name
           align
        menu1:
               dc.l 0             ;no further menu
               dc.w 80,0          ;see above
               dc.w 50,10
               dc.w 1
               dc.l menuname1
               dc.l menuitem11
               dc.w 0,0,0,0
        menuname1:
               dc.b "Menu 2",0    ;second menu name
           align
        menuitem01:               ;first menu item
               dc.l menuitem02    ;pointer to next entry
               dc.w 0,0           ;X/Y
               dc.w 130,12        ;width/height
               dc.w $9f           ;flags
               dc.l 0             ;exclude
               dc.l text01        ;pointer to text structure
               dc.l 0             ;select fill
               dc.b "1"           ;command
           align
               dc.l 0             ;subitem:none
               dc.w 0             ;next select:no
        text01:
               dc.b 0,1           ;colours
               dc.b 0             ;mode:overwrite
           align
               dc.w 5,3           ;X/Y position
               dc.l 0             ;standard character set
               dc.l text01txt     ;pointer to text
               dc.l 0             ;no more text
        text01txt:
               dc.b "Point 0.1",0
           align
        menuitem02:               ;second menu item
               dc.l 0
               dc.w 0,10
               dc.w 130,12
               dc.w $57
               dc.l 0
               dc.l text02
               dc.l 0
               dc.b "2"           ;activate with <Amiga>/'2'
           align
               dc.l 0
               dc.w 0
        text02:
               dc.b 0,1
               dc.b 0
           align
               dc.w 5,3
               dc.l 0
               dc.l text02txt
               dc.l 0
        text02txt:
               dc.b "Point 0.2",0
           align
        menuitem11:               ;first menu point of the second menu
               dc.l menuitem12    ;pointer to second menu point
               dc.w 0,0
               dc.w 90,12
               dc.w $52
               dc.l 0 
               dc.l text11
               dc.l 0
               dc.b 0
           align
               dc.l 0
               dc.w 0
        text11:
               dc.b 0,1
               dc.b 0
           align
               dc.w 5,3
               dc.l 0
               dc.l text11txt
               dc.l 0
        text11txt:
               dc.b "Point 1.1",0
           align
        menuitem12:               ;second menu item of second menu
               dc.l 0             ;no more items
               dc.w 0,10
               dc.w 90,12
               dc.w $92
               dc.l 0
               dc.l text12
               dc.l 0
               dc.b 0
           align
               dc.l submenu0      ;pointer to submenu
               dc.w 0
        text12:
               dc.b 0,1
               dc.b 0
           align
               dc.w 5,3
               dc.l 0
               dc.l text12txt
               dc.l 0
        text12txt:
               dc.b "Point 1.2",0
           align
        submenu0:                 ;first point of submenu
               dc.l submenu1      ;pointer to next point
               dc.w 80,5
               dc.w 90,12
               dc.w $52
               dc.l 0
               dc.l texts0
               dc.l 0
               dc.b 0
           align
               dc.l 0
               dc.w 0
        texts0:
               dc.b 0,1
               dc.b 0
           align
               dc.w 5,3
               dc.l 0,texts0txt,0
        texts0txt:
               dc.b "S Point 1",0
           align
        submenu1:                 ;submenu,second item
               dc.l 0
               dc.w 80,15
               dc.w 90,12
               dc.w $52
               dc.l 0
               dc.l texts1
               dc.l 0
               dc.b 0
           align
               dc.l 0
               dc.w 0
        texts1:
               dc.b 0,1
               dc.b 0
           align
               dc.w 5,3
               dc.l 0
               dc.l texts1txt
               dc.l 0
        texts1txt:
               dc.b "S Point 2",0
           align

        The menu items in this example have the following properties as a 
        result of their flags:

      Menu 1;
        The first item,"Point 0.1",can be chosen using the right <Amiga>
        key and the "1" key.This point alternates between checked and not 
        checked,which can easily be used to check out the key function.If
        the item is checked and you hit both keys,the check disappears and
        vice versa.The box at this point is framed when the mouse pointer 
        clicks on it.
        The second item,"Point 0.2",can be chosen using the right <Amiga> 
        key and the "2"key.This item is checked the first time it is
        chosen.However,in contrast to the item above,it can't be erased.  
        The box of this item is inverted when clicked.

      Menu 2;
        These two points can't be chosen using keys.The box of the upper  
        item is inverted when clicked on:the lower one is framed.When you 
        click the second item,"Point 1.2",a submenu with two entries is
        displayed.

        Experiment with this structure a little bit.Change some values and
        see what happens.As you can see,menu programming isn't as bad as
        you thought,and it offers a lot of options (but you'll have to do
        lots of typing!).
        When you've done experimenting,you'll want to produce your own
        program with menus.How does the program find whether a menu item
        in a menu has been clicked on?
        You already looked at one way to find out the menus state.You can
        test the CHECKED bit in the flag word of a menu item.If this is
        set,the user clicked on this item with the mouse.
        This only works if checking is allowed for the item being tested. 
        You could allow all the menu items to be checked,but this still
        isn't a good solution--it requires testing all the flag bits of
        all the menus one after the other.That makes very boring
        programming.
        You've already learned about finding about events from Intuition. 
        You've moved the message about which event took place into D6,and 
        you can look at it to find out what happend.
        If you set the eight bit,the MENUPICK bit,of the IDCMP flag long
        word in the window definition,the choice of the menu point is
        reported.Put the following lines in your loop in the main program.

        loop:
               move.l  execbase,a6      ;exec base address in A6
               move.l  windowhd,a0      ;window structure pointer
               move.l  86(a0),a0        ;user point pointer in A0
               jsr     getmsg(a6)       ;get message
               tst,l   d0               ;whay happend?
               beq     loop             ;nothing happend
               move.l  d0,a0            ;message pointer in A0
               move.l  $14(a0),d6       ;event in D6

        If the program makes it out of the loop,an event as taken place.  
        You have the events flag in the D6 register.You can evaluate the  
        event using CMP or BTST to find out which flag bits are set.You
        can then execute the function corresponding to the set bit.You can
        use lines like the following ones:

               cmp     #$200,d6         ;WINDOWCLOSE?
               beq     ende             ;yes:program end

        These lines terminate the program when the window is closed.

        If the user chose a menu item,there is a $100 in the D6 register.
        You now need to determine which item it was.
        You can find this information in a word that comes right after the
        long word with the event flags in the message structure.Write:

               move    $18(a0),d7

        You now have the code for the clicked menu item in the D7
        register.If the user just pressed the right key and let it go
        without choosing a menu item,you'll find a $FFFF here.This word
        doesn't contain just one,but three pieces of information:

          Which menu was the item chosen from?
          Which menu item?
          Which submenu?

        The information is divided in three bit groups.The division is as 
        follows:

        Bits  0-4   Menu title number
        Bits  5-10  Menu item number
        Bits 11-15  Submenu item number

        The numbering begins with zero-ie the first menu point of the
        first menu has the numbers 0 and 0.
        
        To try this out insert the following lines:

               move    d7,d6            ;move code into D6
               lsr     #8,d7            ;shift right 11 times
               lsr     #3,d7            ;submenu item now in D7
               clr.l   d5
               roxr    #1,d6            ;bit 0 in X-flag
               roxl    #1,d5            ;menu number now in D5
               and.l   #$7f,d6          ;issolate lower bits
               cmp     #$7f,d6          ;no menu item?
               beq     loop             ;no:continue
               lsr     #4,d6            ;else menu item in D6
               ende

        By making a test run with AssemPro,you can easily see if this
        works right-just look at the registers after the program is over.
 
        If you,for example,want to write a program with four menus with 10
        menu items each,this sort of method is too much work-there are 44 
        tables.For this reason,lets look at a short program that takes
        care of the necessary structure table itself.
        The menu structure is built very simply-it doesn't offer submenus 
        or the option of choosing items via the keyboard.If you want these
        extras,you can still use this program,but you'll have to use MOVE 
        commands to insert the desired flags and pointers.
        The input that this program needs is a list of the menu names and 
        the items in each menu.The addresses of the menu texts go in a
        table with the following simple form:

              dc.l   Menu title 1
              dc.l   Point1,Point2,Point3,...,0
              dc.l   Menu title 2
              dc.l   Point1,Point2,Point3,...,0
              dc.l   Menu title 3 oder 0

        This program is set up in such a way that up to four menus can lie
        next to each other (in normal screen resolution),which is often
        plenty.The table above ends by putting a zero instead of a pointer
        to the nxt menu title.As you can see,its pretty simple.
        This program is inserted in your big program right behind the
        "setmenu"label.After the "bsr setmenu"command is executed,the menu
        structure is built and initialized at the same time.You don't need
        to change the rest of the program,it'll be shorter that way.

        Heres the program fragment for the complete "setmenu"routine:

        setmenu:                        ;*initialize menu structure
               lea     mentab,a0        ;pointer to text pointer in A0
               lea     menu,a1          ;pointer to menu field in A1
               move    #10,d1           ;horizontal menu position=10
 
        menuloop:
               clr.l   d2               ;vertical menu position=0
               move.l  a1,a2            ;save address of pointer
               tst.l   (a0)             ;another menu there?
               beq     setmenu1         ;no:quit
               clr.l   (a1)+            ;"no more menus"preperations
               move    d1,(a1)+         ;set X-position
               add.l   #70,d1           ;and increment
               move.l  #50,(a1)+        ;Y-position and width
               move.l  #$a0001,(a1)+    ;height and flag
               move.l  (a0)+,(a1)+      ;menu title
               lea     12(a1),a3
               move.l  a3,(a1)+         ;pointer to menu item
               clr.l   (a1)+            ;reserved words
               clr.l   (a1)+

        itemloop:
               tst.l   (a0)             ;last entry?
               beq     menuend          ;yes:menu done
               lea     54(a1),a3
               move.l  a3,(a1)+         ;pointer to next item
               move.l  d2,(a1)+         ;X- and Y-positions
               add     #10,d2           ;Y-position+10
               move.l  #$5a000a,(A1)+   ;WIDTH/HEIGHT
               move    #$52,(a1)+       ;flag:normal
               clr.l   (a1)+            ;no connection
               lea     16(a1),a3
               move.l  a3,(a1)+         ;text structure pointer
               clr.l   (a1)+            ;no fill structure
               clr.l   (a1)+            ;no command,no submenu
               clr.l   (a1)+            ;and no continuation
               move    #$1,(a1)+        ;set text structure:colour
               clr.l   (a1)+            ;mode 0
               move.l  #$50003,(a1)+    ;X- and Y-position
               clr.l   (a1)+            ;standard character set
               move.l  (a0)+,(a1)+      ;text pointer
               clr.l   (a1)+            ;no continuation
               bra     itemloop         ;next item...

        menuend:                        ;eventual transfer to next menu
               clr.l   -54(a1)          ;erase pointer to next item
               tst.l   (a0)+            ;increment table pointer
               tst.l   (a0)             ;another menu there?
               beq     setmenu1         ;no:done
               move.l  a1,(a2)          ;pointer to next menu
               bra     menuloop         ;and continue
        setmenu1:                       ;*initialize menu (like before)
               move.l  intbase,a6       ;intuition base address in A6
               move,l  windowhd,a0      ;window structure in A0
               lea     menu,a1          ;pointer to menu structure
               jsr     setmenustrip(a6)
               rts

        You need three things yet for this program:the memory to be used
        for the structure,the table of text pointers and the text.Heres an
        example:

        mentab:
               dc.l menu1               ;first menu title
               dc.l mp11,mp12,mp13      ;menu items
               dc.l 0                   ;end of menu 1
               dc.l menu2               ;second menu title
               dc.l mp21,mp22,mp23      ;menu items
               dc.l 0                   ;end of menu 2
               dc,l 0                   ;you're out of menus!

        ;** Menu Text **
        menu1: dc.b "Menu 1",0
        mp11:  dc.b "Point11",0
        mp12:  dc.b "Point12",0
        mp13:  dc.b "Point13",0
        menu2: dc.b "Menu 2",0
        mp21:  dc.b "Point21",0
        mp22:  dc.b "Point22",0
        mp23:  dc.b "Point23",0
            align
        ;** Storage space for menu structure **
        menu:  blk.w 500

        Make sure that the memory area reserved for the menu structure is 
        big enough and change the entry "blk.w 500"to the calculated
        value. 
        If you use this program,and want to build some special features
        into the menu (for instance key commands),you can make entries in
        the menu structure table while the program is running.You can find
        the word (or byte or long word) that interests you in the table as
        follows:

        For example,to find the keyboard command byte of the second entry
        in the first menu,calculate as follows:

        Address = Start_address+Menu*30+(entry-1)*54+26

        which in the example comes to:

        Address = menu+30+54+26
                = menu+110

        The 26 is the distance from the beginning of the MenuItem
        structure to the desired byte,the command byte.In this way,you can
        calculate the addresses and use MOVE commands to modify the menu
        to fit your wishes.By the way,in the example above,the correspond-
        ing flag bit must be set as well,so that the keyboard command is  
        recognized.
        Now lets get back to the window.Its nice to have a window that you
        can change and close,but you really want to be able to output text
        in a window!

      7.6.Text Output.
      ----------------
        Its very easy to use Intuition's text output function.Use the
        PrintIText function (offset -216).It needs four parameters.

        In A0    A pointer to the RastPort of the window.You can find this
                 in the window structure.
        In A1    A pointer to the text structure of the text that should
                 be output.
        In D0    The X-position.
        In D1    The Y-position of the text in the window.

        Its very easy to enter the X- and Y-positions.You've already used 
        the text structure twice (for requesters and menus).
        Whats new is accessing the windows RastPort.The RastPort is a
        structure that describes the window.The address is needed by
        several Intuition functions.
        The pointer to the RastPort starts at the 50th byte in the window 
        structure.You can access it as follows:
 
            move.l  windowhd,a0           ;address of window structure
            move.l  50(a0),a0             ;RastPort address in A0

        Now you've got the address of the RastPort.Lets write a routine
        that prints a text.The X- and Y-positions are in D0 and D1
        respectively and the address of the text structure in A1 before
        the routine is called:

        PrintIText = -216
               ...
        print:
               move.l  intbase,a6       ;intuition base address in A6
               move.l  windowhd,a0      ;address of window structure
               move.l  50(a0),a0        ;rastport address in A0
               jsr     printitext(a6)   ;call function
               rts

        You can try out this routine by using the requesters text that is 
        still in a structure of the program.Write the following lines
        before the "loop"label:

               lea     btext,a1         ;pointer to text structure in A1
               move.l  #10,d0           ;X-position
               move.l  #30,d1           ;Y-position of text
               bsr     print            ;output text

        Start the program and the text appears in the middle of the window
        If this doesn't happen,check the colour of the text in the text   
        structure.Its probably zero.Just change it to three,and the text  
        appears in red the next time you start the program.

      7.7.Images.
      -----------
        An image is a drawing that goes in a rectangular field and is
        defined bitwise.The disk symbol of the Intuition screen and the   
        system gadgets in the screen and window borders are examples of
        such Images.
        The rectangle that the drawing goes in can be arbitrarily large,  
        but each pixel in the rectangle needs its own bit,so programming  
        screen-sized Images isn't advisable.You'll stick to an Image that 
        requires about 32x16 bits-an Image thats about 3x1cm.
        You can make all sorts of images as you've seen looking at window 
        gadgets.There is an Intuition functionthat draws an Image:It is
        the DrawImage function (offset -114) and it needs 4 parameters:

        In A0   The address of the rastport image is drawn in.You've
                already learned how to access this address in the section 
                on the text function.
        In A1   The structure address of the image to be drawn.
        In D0   The relative X-position
        In D1   The relative Y-position of the drawing.

        Lets draw this picture in your window.It justs takes a simple
        routine.You just need to put the address of the image structure in
        A1 and the position of the image in D0 and D1 before you call it.

        DrawImage =-114
               ...
        draw:                           ;*draw image
               move.l  intbase,a6       ;intuition base address in A6
               move.l  windowhd,a0      ;pointer to window structure
               move.l  50(a0),a0        ;now,rastport address in A0
               jsr     drawimage(a6)    ;draw image
               rts

        Now you need the structure of the image.The structure contains
        nine entries which have the following meanings:

        The first two entries are words which specify the distance in the 
        X- and Y-direction from the co-ordinates that were given to tell  
        where the image should be drawn.You'll just put two zeros here:

        image:
               dc.w  0,0                ;X- and Y-position

        Next come two words which specify the width and height of the
        image in pixels.Lets draw a 32x13 point image.Enter: 

               dc.w  32,13              ;width and height of image

        The next word in the list specifies the number of planes in the
        drawing.If its a simple image that only uses two colours,just
        enter a one.For more colours,you'll need a correspondingly bigger 
        number.When more colurs are worked with,the bit pattern of the
        image must have more data.Lets just have one bit plane:

               dc.w  1                  ;one bitplane:2^1=2 colours

        Next comes a long word that points to the data of the image:

               dc.l  imgdata            ;pointer to image data

        The next two bytes are very interesting.The first byte,the
        PlanePick byte,tells which plane of the window or screen the image
        data should be written in.Since you only have one plane,you need
        to enter the bit plane of the window.This information is found in
        the bits of the byte-bit0 stands for plane 0,bit 1 for plane 1,etc
        ..You also define the colour of the image with this input.If you
        enter a two,every set bit of your image represents a red point.

               dc.b  2                  ;drawing red:plane 1

        The second byte,the PlaneOnOff byte,is an interesting enhancement.
        Each bit of the window bit plane corresponds to a whole number
        here.The only bytes that are interesting though are the ones that
        are cleared in the PlanePick byte.If the bit is set in PlaneOnOff,
        evert bit of the image in the corresponding plane is set.Otherwise
        they are cleared.To make sure that each bit of the image that
        isn't set appears white,enter a one.All the bits of the image that
        aren't set,are set in Plane 1 and appear white.

               dc.b  1                  ;background:white

        The last entry of the structure is a lobg word that points to
        another image.You don't need this,so set the long word to zero:

               dc.l  0                  ;no more images

        Heres a quick overview of the image structure:
       
        image:
               dc.w  0,0                ;X- and Y-positions
               dc.w  32,13              ;width and height of image
               dc.w  1                  ;one bitplane:2^1=2 colours
               dc.l  imgdata            ;pointer to image data
               dc.b  2                  ;drawing red:plane 1
               dc.b  1                  ;background:white
               dc.l  0                  ;no more images

        Now lets produce the image data.Each image row uses a word,long
        word,or several of these represent the pattern.The set points of
        the image correspond to the set bits.This is repeated as often as 
        the height of the image requires.The data on each line must begin 
        on a word border,on a even address.
        For the example,its easy to decide on the data,since you're going 
        32 points across-that corresponds to exacty one long word.Its
        easiest to program the image using the binary representation of
        the data.
        Lets use,as an example,an image that represents a switch in "OFF" 
        mode.This form is chosen for a good reason,so you should type it
        in.In the chapter on gadgets thats coming up,we'll show you how to
        turn the switch on.Here is the example data for the switch image:

        imgdata:   ;Data for switch in "OFF" mode
           dc.l    %00000000000000000000000000000000
           dc.l    %00000000000000000000111000000000
           dc.l    %00011101110111000001111100000000
           dc.l    %00010101000100000001111100000000
           dc.l    %00010101100110000001111000000000
           dc.l    %00011101000100000011100000000000
           dc.l    %00000000000000000111000000000000
           dc.l    %00000000000000001110000000000000
           dc.l    %00000000000111111111100000000000
           dc.l    %00000000001111111111110000000000
           dc.l    %00000000001111111111110000000000
           dc.l    %00000000000110000001100000000000
           dc.l    %00000000000000000000000000000000

        Once you've typed in this data,you can experiment with displaying
        it on the screen.Enter the following lines before the "loop"label:

            move.l  image,a1           ;pointer to image structure
            move    #30,d0             ;X-postion in window
            move    #50,d1             ;Y-position
            bsr     draw               ;draw image

        How do you like the image on the screen?You'll run into this
        switch again when we talk about putting the switch in the "ON"    
        state when discussing gadgets.You need to look at other methods of
        drawing in the window first,though.

      7.8.Borders.
      ------------
        A border is a collection of lines that are connected.They can be
        of any length or at any angle.Intuition lets you draw borders to
        do things like put frames around windows and screens.They are used
        to put borders around pictures or text,especially for use with
        string gadgets.We'll talk about that later,though.
        Its easy to draw borders.Just use the Intuition function
        DrawBorder (offset -108) which needs four parameters:

        In A0   The rastport address of the output medium the lines should
                be drawn in.Use your window.
        In A1   The address of the border structure.We'll look at the form
                of this structure shortly.
        In D0   The relative X-co-ordinate which is used with the X- and Y
                co-ordinate list to calulate the actual line co-ordinates.
        In D1   The relative Y-co-ordinates.Relative,here too,means that
                this is relative to the upper left corner of the screen.

        Lets write a short routine that is called with three parameters.  
        The structure address in A1 and the X and Y co-ordinates are in D0
        and D1 respectively when the routine is called.The border is drawn
        in the window whose structure address is in "windowhd".

        DrawBorder =-108
               ...
        borderdraw:                     ;* draw several lines
               move.l  inbase,a6        ;intuition base address in A6
               move.l  windowhd,a0      ;pointer to window structure
               move.l  50(a0),a0        ;now rastport address in A0
               jsr     drawborder(a6)   ;draw lines
               rts

        Now lets look at the border structure.The list needs the eight
        following parameters:

        First,you need two words for the vertical and horizontal distance 
        from the co-ordinates given in the function call.To avoid losing  
        sight of some of the many distance entries,put two zeros here:

        border:
               dc.w  0                  ;horizontal distance
               dc.w  0                  ;vertical distance

        Next come two bytes that determine the colour.Use a red frame:

               dc.b  3                  ;red frame
               dc.b  0                  ;background (unused)

        As you can see,the background colour isn't used.You have two modes
        to choose between for drawing the lines.The following mode
        determines the mode that is used.If it is zero,each line is drawn
        in the colour chosen,no matter what was done before.This is the
        JAM1 mode.The other mode is the XOR mode which ignores both colour
        entries.In this mode,all the points that lie under the line have
        their colour value inverted.As a result,a white point becomes
        black,and a blue one becomes red.That is mode two.Lets use the
        JAM1 mode for the example:

               dc.b  0                  ;mode:JAM1 (2=XOR)

        The next entry specifies how many co-ordinate pairs there are in
        the list.Since this word must be on an even address,you need to
        use the "align"peudo-op first.Then enter the number of pairs.     
        Remember that you need three points to draw two lines:beginning,  
        corner and end point.To draw a rectangular frame,you need five
        pairs:

               dc.b  5                  ;5 X,Y pairs used together

        The next item is a pointer to the co-ordinate table that contains
        a list of points to be connected:

               dc.l  coord              ;pointer to cordinate table

        The border structures final entry is a long word that can point to
        another border structure.If you don't have any more structures to
        be pointed to,just enter a zero here.The pointer is useful for
        connecting two independant border structures-for example,to
        produce a two coloured frame that really stands out.You don't need
        this pointer in the example,though:

               dc.l  0                  ;no more structures

        Thats the border structure.Now lets look at the co-ordinate list.
        For the example,it consists of five pairs of numbers which
        represent a rectangle.I recommend entering these values,because
        you'll use them in example programs further down the line.

        coord:                          ;coordinates for rectangle frame
               dc.w  -2,-2
               dc.w  80,-2
               dc.w  80,9
               dc.w  -2,9
               dc.w  -2,-2

        Heres a quick overview of the border structure:

        border:
               dc.w  0                  ;horizontal distance
               dc.w  0                  ;vertical distance
               dc.b  3                  ;red frame
               dc.b  0                  ;background (unused)
               dc.b  0                  ;mode:JAM1 (2=XOR)
               dc.b  5                  ;5 X,Y pairs used together
               dc.l  coord              ;pointer to cordinate table
               dc.l  0                  ;no more structures
        coord:                          ;coordinates for rectangle frame
               dc.w  -2,-2
               dc.w  80,-2
               dc.w  80,9
               dc.w  -2,9
               dc.w  -2,-2

        Once you've typed this in,you can try the whole thing out.Type the
        following lines before the "loop"label in the program:

               lea     border,a1        ;address of the border structure
               move    #20,d0           ;X base position
               move    #80,d1           ;Y base position
               bsr     drawborder       ;draw frame

        As you can see,using enough X and Y co-ordinates,you can draw the 
        Eiffel tower.Thats enough about simple drawings.You want to put
        some life into your drawings and text.Lets manipulate them with
        the mouse!

      7.9.Gadgets.
      ------------
        We already talked a bit about gadgets when you looked at screen
        construction.Looking at system gadgets like the window close
        symbol,you can activate by clicking and causes a program function 
        to be executed.
        You can make your own gadgets as well.Intuition allows you a lot
        of interesting possibilities.
        
        There are four types of gadgets:

        Boolean gadgets are used in Yes/No situations.You can click and
        activate it (Yes) or deactivate it (No).

        String gadgets are used to accept input of text of a specified
        length.
 
        Integer gadgets are a special sort of string gadgets which accept
        the input of a decimal number.Intuition converts the value into a 
        long word and sends it to the program.

        Proportional gadgets let you choose an analog value with the mouse
        You can move these around with the mouse.

      7.9.1.Boolean Gadgets.
      ----------------------
        Lets start with the simplest type,the boolean gadget.an example of
        this sort of gadget is the close symbol of the window.The only
        status it differenciates between are clicked and not clicked.Lets 
        develop a gadget of this type step by step.The flags and other    
        parameters are similar for the other gadgets.
        Each gadget needs a structure containing fifteen entries.There is
        a pointer to this structure in window,screen or requester that the
        gadget is to appear in.Theres always a long word available for
        this purpose.Up to this point,you've just put a zero there.If
        there is an address of a gadget structure there,the gadget or
        gadgets are displayed when the window is opened.

        A gadget structure as the following entries:

        The first long word is a pointer to the next gadget to be
        installed.The gadgets are displayed in a row,like pearls on a
        string.This pointer is the first gadget in this linked list of
        gadgets.If you just want one gadget in your window,put a zero
        here:
       
        gadget1:
               dc.l  0                  ;no more gadgets

        The next two words determine the position of the gadget in the
        window.There are several ways to determine the position.Use flags 
        to access the various possibilities.Lets start with a gadget that 
        stays in one spot:

               dc.w  40                 ;X and
               dc.w  50                 ;Y position of the gadget

        The next two words determine the size of the gadgets Hit box.This 
        box isn't the visible size of the gadget (that depends on the
        image data).It is the size of the rectangle that Intuition should 
        watch.If the mouse pointer is moved into this box and the left
        button pressed,the gadget is activated.Clicking on parts of the
        gadget that are outside this box have no effect!

               dc.w  32                 ;width and
               dc.w  13                 ;height of the hit box

        Next comes the word whose bits determine the properties of the
        gadget.Bits 0 and 1 determine what should happen when this objects
        hit box is clicked on.The meanings of the various values of these
        bits go as follows:

        Bit 0   1   Value   Name          Meaning
        ------------------------------------------------------------------
         0      0     0     GADGHCOMP     The gadget inverted
         0      1     1     GADGHBOX      The gadget framed
         1      0     2     GADGHIMAGE    Another image appears
         1      1     3     GADGHNONE     No reaction

        Bit 2 determines whether the gadget should consist of a drawing or
        a border.If it is set(Value+4),it is treated as an image;otherwise
        its treated like a border.
        The next bit determines if the gadget should appear in the upper
        or lower border of the frame.If it is set(Value+8).the position is
        relative to the lower border;otherwise it is relative to the upper
        border.The next bit as the same meaning for the horizontal
        position.If set(Value+$10),it is a relative positioning.Otherwise,
        it is an absolute positioning.
        Notice that when you define a gadget to be relative,you must have
        a negative value in the position input in the first word of the
        structure.Since the desired position isn't under,but its over this
        position!
        In this way,you can choose either absolute or relative positioning
        of the gadget.An example of a gadget that is positioned absolutely
        is the system gadget,close window.An example of a relative gadget 
        is the symbol for changing the size.
        The width and height of the gadgets hit box can also be relative
        to the window size.Specify this by using bit 5 for width (Value +
        $20)and bit 6 for the height (Value +$40).A set bit mens a
        relative size.
        Bit 7 (Value+$80)makes the object active as soon as the window is
        opened.
        Bit 8 (Value+$100)determines whether the gadget can be used or not
        If this bit is set,the gadget can't be activated.
        For the example,you'll use absolute positioning and size,the
        inverted appearance for the activated gadget,and the
        representation of the object as an image.That means you must use
        the value four:

              dc.w  4              ;flags:image,invert

        Next comes a word whose bits are used as flags.This flag is called
        the Activation Flag.It determines the functions of the gadget.The 
        bits,their values and meanings follow:

        Bit   Value   Name            Meaning
        ------------------------------------------------------------------
         0     1      RELVERIFY       Causes the gadget to be activated
                                      only when the left mouse key is let
                                      loose over the gadget.
         1     2      GADGIMMEDIATE   Lets the gadget be active as soon as
                                      there is a click.
         2     4      ENDGADGET       Lets you choose to end this choice
                                      and have it disappear if this is a  
                                      requester gadget.
         3     8      FOLLOWMOUSE     Lets the gadget know the mouse
                                      position at regular intervals from
                                      the time it is selected until the
                                      time it is deselected.You can use
                                      this to move the gadget with the
                                      mouse when you want to change the
                                      gadget position.
         4     $10    RIGHTBORDER     This makes sure thay when borders
                                      are used that the page is adjusted
                                      to the size of the gadget so that it
                                      fits in the border.
         5     $20    LEFTBORDER
         6     $40    TOPBORDER
         7     $80    BOTTOMBORDER
         8     $100   TOGGLESELECT    Allows the objects state to change  
                                      every time it is clicked.If
                                      activated,it becomes deactivated and
                                      vice versa.
         9     $200   STRINGCENTRE    For a string gadget,these two bits  
                                      determine whether the string should 
                                      appear centred or right justified.If
                                      neither is set,the string is output 
                                      left justified.
         10    $400   STRINGRIGHT
         11    $800   LONGINT         Turns a string gadget into a Integer
                                      gadget (explanation later).
         12    $1000  ALTKEYMAP       Causes another ketboard placement to
                                      be in effect for string gadget input

        Thats it for the activation flags.Lets choose the TOGGLESELECT and
        GADGETIMMEDIATED flags for example:

             dc.w  $102             ;activation

        The next word of the gadget structure determines the gadget type. 
        Heres the meaning of the individual bits:

        Bit   Value   Name            Meaning(report what circumstances)
        ----------------------------------------------------------------
         0     1      BOOLGADGET      This is a boolean gadget
         1     2      GADGET002       
         2     4      STRGADGET       String order Integer gadget
        0+1    3      PROPGADGET      Proportional gadget

        System gadgets:
         4     $10    SIZING          Size changing gadget
         5     $20    WDRAGGING       Moving gadget for window
        4+5    $30    SDRAGGING       Same for screen
         6     $40    WUPFRONT        Gadget to move window forward
        6+4    $50    SUPFRONT        Gadget to move screen forward
        6+5    $60    WDOWNBACK       Move window back
        6+5+4  $70    SDOWNBACK       Move screen back
         7     $80    CLOSE           Window close gadget

        Type definitions:
         12    $1000  REQGADGET       Requester gadget
         13    $2000  GZZGADGET       Border gadget in GIMMEZEROZERO
                                      window
         14    $4000  SCRGADGET       Screen gadget when set
         15    $8000  SYSGADGET       System gadget when set

        You want to use a simple boolean gadget for your example,so enter:

               dc.w  1                ;gadget type:boolean

        Next comes a pointer to the gadget structure.The first pointer
        contains the address of the image or border structure which should
        be used to represent the gadget.If no representation is needed,put
        a zero here.You want to represent the gadget as an image,so put a 
        pointer to the image structure that you produced in the chapter
        about images:

               dc.l  image            ;gadget image

        The next pointer is only used if the GADGHIMAGE flag in the flag
        word of the structure is set.This is a pointer to another
        structure that should be put on the screen when the object is
        activated.If a border structure is used for the gadget represent- 
        ation,this must be a border structure as well.You won't use a
        second image,so put a zero here:

               dc.l  0                ;no new gadget displayed

        The next pointer is to the text structure that should be output by
        the gadget.If no text is needed,just put a zero here.You want to
        use some text,however:

               dc.l  ggtext           ;gadget text

        Now comes a long word that determines which gadgets are
        deactivated when this is activated.This function still doesn't
        work right so put a zero here:

               dc.l  0                ;no exclude

        You'll set the next pointer to zero as well,because it is only
        used for String and Proportional gadgets.For these gadgets,this is
        a special structure to describe the characteristics of the gadget.
        Its called SpecialInfo.

               dc.l  0                ;no SpecialInfo
 
        The next word contains the Gadget Identification (ID) number:

               dc.w  1                ;gadget ID

        Finally there is a long word that doesn't have any function,so put
        a zero here:

               dc.l  0                ;user data (ignore)

        Thats it.Heres a quick overview of the gadget structure:

        gadget1:
               dc.l  0                ;no more gadgets
               dc.w  40               ;X and
               dc.w  50               ;Y position of gadget
               dc.w  32               ;width and
               dc.w  13               ;height of hit box
               dc.w  4                ;flags:image,invert
               dc.w  $102             ;activation flags
               dc.w  1                ;gadget type:boolean
               dc.l  image            ;gadget image
               dc.l  0                ;no new gadget displayed
               dc.l  ggtext           ;gadget text
               dc.l  0                ;no exclude
               dc.l  0                ;no SpecialInfo
               dc.w  1                ;gadget ID
               dc.l  0                ;user data (ignore)

        You've already prepared a structure that you can use for this
        image.Now you need the text that appears under the gadget.
        Since the gadget looks like a switch,label it "switch".The text
        structure looks like this:

        ggtext:
               dc.b  1,0              ;colours
               dc.b  1                ;mode
           align
               dc.w  -8,14            ;X and Y position
               dc.l  0                ;standard font
               dc.l  swtext           ;pointer to text
               dc.l  0                ;no more text
        swtext:
               dc.b  "switch",0
           align

        Once you've typed this in,save it,assemble it and start again.You 
        can click the switch and cause it to be inverted.Click it again,  
        and it appears normal.
        Now you can experriment with the structure.If you change the flag 
        from four to five,you can cause the gadget to be framed when it is
        activated.Set the RELVERIFY bit(bit0:+1)in the Activation Flag
        word.Then you can move the mouse pointer onto the object and press
        the button.It is activated.Keep the mouse button pressed down and 
        move the mouse.Once you leave the hit box,the activation disapears
        This way,you can avoid accidently activating a gadget.
        Now you want to display the switch in an on state.This is easy.All
        you need to do is produce another image structure,one for the on  
        state.You put this pointer in the long word right after the
        pointer to the normal image structure.You can change the flag word
        to six which causes a second image to be displayed when the gadget
        is activated.
        Here is the image structure for the switch in the one state.

        image2:
               dc.w  0,0              ;no offset
               dc.w  32,13            ;32x13 pixels
               dc.w  1                ;mode 1
               dc.l  imgdata2         ;pointer to the data
               dc.b  2,1              ;same colours as before
               dc.l  0                ;nothing else
       
        imgdata2:                     ;data for switch in the On state
               dc.l  %00000000000000000000000000000000
               dc.l  %00000000011100000000000000000000
               dc.l  %00000000111110000011101001000000
               dc.l  %00000000111110000010101101000000
               dc.l  %00000000011110000010101011000000
               dc.l  %00000000000111000011101001000000
               dc.l  %00000000000011100000000000000000
               dc.l  %00000000000001110000000000000000
               dc.l  %00000000000111111111100000000000
               dc.l  %00000000001111111111110000000000
               dc.l  %00000000001111111111110000000000
               dc.l  %00000000000110000001100000000000
               dc.l  %00000000000000000000000000000000

        Now the state of the object can be determined by looking at the
        picture.If the gadget is activated,the switch is on.If not,the
        switch is off.
        Thats it for boolean gadgets.You can learn about the things you
        did'nt touch with some experimentation.You want to get to the
        string gadgets that also do some interesting things.

      7.9.2.String Gadgets.
      ---------------------
        Lets pretend you want a program to load data from the disk.To get 
        the user to enter the filename,you need to output text telling the
        user to enter the name.Then you need to call an input routine to
        evaluate the keyboard input.
        Its easier and more elegant to use a String gadget.This function  
        allows for easy input and/or editingof short text.You have the
        option of having the text framed.The Undo function can be used by 
        pressing the right <Amiga> key and a "Q",and the old contents of
        the gadget,the old text are restored.
        You can also vary the size of the text and the input field.If the 
        text is longer than the input field is wide,the text is moved back
        and forth through the visible area when you move the cursor keys
        or the normal input to the border.
        You can also restrict input to just digits.This makes it posible
        to accept numeric input.Intuition even converts the digit string  
        into a binary number.This saves the machine language programmer
        some work.A specialized String gadget of this sort is called a    
        Integer gadget.
        The structure is similar to the Boolean gadgets structure.There
        are only two major differences:

        The type word of the structure must be a four to declare that this
        is a String gadget (STRGADGET).
  
        The pointer to the SpecialInfo structure is needed.Put a pointer
        to the StringInfo structure that you are going to design later
        here.

        The width and height entries in the gadget structure have a
        different meaning than they had previously.They do declare the
        area in which you can bring the mouse pointer to activate the
        String gadget.However,it is also used for representation of text. 
        These values determine the size of the box in which the text is
        output.You should surround the box with a border using the Border 
        function,so that the user can see where it is.
        If the text is longer than the box,only a portion of it is seen on
        the screen.You can move through the area by entering text or using
        the left/right cursor keys to move through the box.The characters 
        that are entered are inserted at the cursor position,so the rest
        of the text is shifted by one character when you are on the right 
        edge of the input area.The following functions can be used for
        editing this text:

        Cursor key left/right
              Moves the cursor over the text thats already on hand.Moves
              the text through the Container.

        Cursor keys with <Shift>
              Puts the cursor on the beginning or the end of the text.

        <Del> Deletes the character under the cursor.

        <Backspace>
              Deletes the character to the left of the cursor.

        <Return>
              Ends text input.

        <Amiga>right+"Q"
              This is the Undo function.It replaces the text with the
              original contents.

        The StringInfo structure only has a few entries:

        First theres a pointer to the memory area that is used to store
        the text that is input.The memory buffer must be big enough to
        handle all the text entered.

        strinfo:
               dc.l  strpuffer        ;pointer to text buffer

        Next comes the pointer to the Undo buffer.This pointer and this
        buffer are only needed if you want the Undo function.If you do,you
        must have a buffer that is at least as big as your text buffer.   
        Every time the string gadget function is called,the text buffers  
        contents are copied into this buffer.To get the old contents back,
        just press the right <Amiga>key and the "Q"key.The contents of the
        Undo buffer are copied back to the text buffer.If you use several 
        string gadgets in a program,you can use the same Undo buffer for
        all of them,since only one string gadget is used at one time.

               dc.l  undo             ;pointer to undo buffer

        The following word contains the cursor position in the text.You   
        should set this word to zero,so that the user can see the
        beginning of the text when the string gadget appears.

               dc.w  0                ;cursor position

        The next word contains the maximum number of characters that can
        be input.If you type one more than this number of characters,the  
        screen blinks,to show that you can't enter a longer input string. 
        The number of characters and the reserved space for the input
        field don't have to agree,since text can be scrolled by typing.

               dc.w  10               ;maximum # of characters

        The following word tells at which character of text in the buffer,
        the output to the box should begin.You should put a zero here,so
        that the user can see the beginning of the text.

               dc.w  0                ;output text from this character

        The next five words are used by Intuition,so you don't have to    
        initialize them.Just put zeros here.The words contain the
        following information:

               dc.w  0                ;character position in undo buffer
               dc.w  0                ;number of chars in text buffer
               dc.w  0                ;number of chars visible in box
               dc.w  0                ;horizontal box offset
               dc.w  0                ;vertical box offset

        The next two long words are initialized by Intuition as well:

               dc.l  0                ;pointer to rastport
               dc.l  0                ;long word with value of the input
        ;                             ;(for integer gadgets)

        The final entry is a pointer to the keyboard table that is used if
        the ALTKEYMAP flag of the gadget is set.

               dc.l  0                ;standard keyboard table

        Heres a quick overview of the StringInfo structure:

        strinfo:
               dc.l  strpuffer        ;pointer to text buffer
               dc.l  undo             ;pointer to undo buffer
               dc.w  0                ;cursor position
               dc.w  10               ;maximum # of characters
               dc.w  0                ;output text from this character
               dc.w  0                ;character position in undo buffer
               dc.w  0                ;number of chars in text buffer
               dc.w  0                ;number of chars visible in box
               dc.w  0                ;horizontal box offset
               dc.w  0                ;vertical box offset
               dc.l  0                ;pointer to rastport
               dc.l  0                ;long word with value of input
        ;                             ;(for integer gadgets)
               dc.l  0                ;standard keyboard table

        Here are the text and undo buffers:

        strpuffer:
               dc.b  "Hello!",0,0,0

        undo:
               dc.l  0,0,0,0
           align

        Once you've entered these lines,you can either alter the old
        gadget structure or build a new one.We'd recommend building
        another gadget structure so that you can have the switch and use
        it later.Change the first pointer in the old structure from zero
        to "gadget1"and insert this new structure.Here is an example
        strucure for the string gadget.It as the following entries:

        gadget1:                      ;*structure for string gadget
               dc.l  0                ;no more gadgets
               dc.w  20,80            ;position
               dc.w  80,10            ;width and height of box
               dc.w  0                ;flags:normal
               dc.w  2                ;activation($802 for long int)
               dc.w  4                ;type:string gadget
               dc.l  border           ;pointer to border
               dc.l  0                ;no drawing selected
               dc.l  0                ;no text
               dc.l  0                ;no exclude
               dc.l  strinfo          ;pointer to stringinfo structure
               dc.w  2                ;gadget ID
               dc.l  0                ;no user data

        border:                       ;*border for box frame
               dc.w  0,0              ;no offset
               dc.b  3,3              ;red colour
               dc.b  0                ;mode:JAM1
               dc.b  5                ;5 X,Y pairs
               dc.l  coord            ;pointer to coordinates table
               dc.l  0                ;no more structures

        coord:                        ;*coordinates for frame
               dc.w  -2,-2            ;start in upper left corner
               dc.w  80,-2            ;upper right
               dc.w  80,9             ;lower right
               dc.w  -2,9             ;lower left
               dc.w  -2,-2            ;back to beginning

        This data causes a red rectangle,the border,to appear around the  
        "Hello!"text.You can change the text by clicking in the field and 
        editing once the cursor appears.If you type something wrong,you
        can use the undo function(the right <Amiga> key and the Q key),to 
        get "Hello!"back.
        Once you've done some typing and deactivated the gadget by
        pressing <Return> or by clicking outside the field (cursors
        disapear),you can terminate the program.
        Change the activation flag to $802 and the "strbuffer"to "dc.l
        0,0,0,0",assemble,and then start the program.You can type in the
        string gadget once it has been activated,but you can only enter
        digits.The screen blinks if you enter letters.
        Enter a number,and then end the program after deactivating the
        gadget.If you look at the stringinfo structure you can look at the
        value of the number you input(in hex)in the eight long word.
        After looking at boolean,text and numeric input to gadgets,lets
        look at Proportional gadgets which allow the user to enter analog 
        values by moving a symbol.

      7.9.3.Proportional Gadgets.
      ---------------------------
        You've seen the advantages of slider devices over knobs that you
        turn,maybe on a hifi,maybe on a toaster,but certainly someplace.
        Its easier to tell the state the item is in with a slider,
        especially if several such devices are next to each other(for
        example graphic equalizers).You can represent sliders on the
        Amigas screen and work with them with the mouse.This offers a nice
        way to represent information graphically in your programs.
        You can do this with gadgets.Using Proportional gadgets,you can
        put a symbol in a frame and move horzontally and/or vertically.The
        size of the frame and the slider can be variable size,so that the
        frame size is relative to the screen size so when the window
        changes size,it will also.The slider can be set up so that its
        size in the grows or shrinks.
        These are best seen via example and experimentation.(The
        posibilities mentioned do not form a complete list by any stretch 
        of the imagination.)You want to set up a simple Proportional
        gadget that can be moved horizontally.
        You need a gadget structure that as the same form as others.To
        show the differences,heres a complete example structure for your  
        gadget.You can connect this gadget to the other one,by changing
        the first long word in the last structure to "dc.l gadget2".

        gadget2:                      ;*structure for Proportional gadget
               dc.l  0                ;no more gadgets
               dc.w  150,30           ;position
               dc.w  100,10           ;width and height of frame
               dc.w  4                ;flags:GADGIMAGE
               dc.w  2                ;activation:GADGIMMEDIATE
               dc.w  3                ;type:proportional gadget
               dc.l  mover            ;pointer to slider data
               dc.l  0                ;no select structure
               dc.l  0                ;no text
               dc.l  0                ;no exclude
               dc.l  propinfo         ;pointer to propinfo structure
               dc.w  3                ;gadget ID
               dc.l  0                ;no user data

        You see two special features.Use an image structure for the mover 
        and put a pointer to another structure in the spot for the Special
        Info pointer.
        First,lets look at the "mover"structure,the sliders image
        structure.Heres an example of this structure:

        mover:                        ;*structure for slider image
               dc.w  0,0              ;no offset
               dc.w  16,7             ;16x7 pixels big
               dc.w  1                ;one bit plane
               dc.l  moverdata        ;pointer to image data
               dc.b  1,0              ;colour:white
               dc.l  0                ;don't continue

        moverdata:                    ;*image data for mover
               dc.w %0111111111111110
               dc.w %0101111111111010
               dc.w %0101011111101010
               dc.w %0101010110101010
               dc.w %0101011111101010
               dc.w %0101111111111010
               dc.w %0111111111111110

        Up till now,there was'nt anything new.Now lets look at the
        PropInfo structure that describes the properties of the
        Proportional gadget.

        The structure starts with a flag word that contains the following 
        bits:

        Bits   Value   Name              Meaning
        -----------------------------------------------------------------
         0       1     AUTOKNOB          Mover is set up automatically
         1       2     FREEHORIZ         Allows horizontal movement
         2       4     FREEVERT          Allows vertical movement
         3       8     PROPBORDERLESS    Turns off automatic framing
         8      $100   KNOBHIT           Set when the mover is touched

        You can set the first four bits to get the representation that you
        want.Bit 8 is set by Intuition when the mover is clicked with the
        mouse pointer.
        Bit 0,AUTOKNOB,allos for the simplest sort of Proportional gadget.
        If this bit is set,no move data are used for the mover image.
        Instead,a white mover is generated that is adjusted to the size of
        the box and the values to be represented.When you use this slider
        to represent the displayed lines in a long text of a program,the
        displayed lines are a percentage of the total text.The
        relationship between the total number of lines and the lines shown
        is represented by an AUTOKNOB as the relationship between the
        frame and the slider.The bigger the percentage,the bigger the
        slider is.You don't want to work with this though,even though it
        is simple and interesting,because a simple white button isn't
        particularly attractive.If you experiment with it,make sure that
        the pointer to the image data points to a four word long buffer
        that Intuition can use to store values.The buffer is of the
        following form:

        buffer:
               dc.w  0                ;X position of the slider in the box
               dc.w  0                ;Y position in the box
               dc.w  0                ;width of slider
               dc.w  0                ;height of slider

        Leys look at the PropInfo structure.Since you're not using
        AUTOKNOB and wish to allow horizontal movement only,put two in as
        a flag:

        propinfo:
               dc.w  2                ;flags:FREEHORIZ

        In the next two words of the structure,the horizontal (HorizPot)
        and vertical (VertPot) position of sliders are stored.A value of  
        zero means left or upper,while the value $FFFF means right or
        lower.The value that results from movement is in this range.You
        set these values to zero at the start of the program.After moving 
        the mouse,there is different values here.

               dc.w  0,0              ;X and Y position of the slider
 
        Next come two words which determine the size of the AUTOKNOB or
        the step size of the slider(this determines how far the slider
        moves when you click in the box next to the slider).These words
        are called HorizBody (horizontal movement) and VertBody (vertical 
        movement).

               dc.w  $ffff/16         ;horizontal step size:1/16
               dc.w  0                ;no vertical movement
        ;The next six words are initialized by Intuition.
               dc.w  0                ;box width
               dc.w  0                ;box height
               dc.w  0                ;absolute step size horizontal
               dc.w  0                ;and vertical
               dc.w  0                ;left border of box 
               dc.w  0                ;upper border of box

        Thats it.Heres a quick overview of the PropInfo structure:
         
        prpoinfo:
               dc.w  2                ;flags:FREEHORIZ
               dc.w  0,0              ;X and Y position of slider
               dc.w  $ffff/16         ;horizontal step size:1/16
               dc.w  0                ;no vertical movement
               dc.w  0                ;box width
               dc.w  0                ;box height
               dc.w  0                ;absolute step size horizontal
               dc.w  0                ;and vertical
               dc.w  0                ;left border of box
               dc.w  0                ;upper border of box

        Once you've typed this in,you can start the program and try it
        out.
        You can also try vertical movement by setting the flag word equal
        to six,the vertical step size to $FFFF/10,and the height of the
        gadget to 80,for the example.To try out the AUTOKNOBs,change the  
        flag value to seven.

      7.10.Example Program.
      ---------------------
        Here is a complete example program using what you have learned in
        this chapter:

        ;7_Intuition.asm
        ;** Demo-Program for working with Intuition **

        movescreen    =-162
        openscreen    =-198
        closescreen   =-66
        openwindow    =-204
        closewindow   =-72
        autorequest   =-348
        setmenustrip  =-264
        clearmenustrip=-54
        printitext    =-216
        drawimage     =-144
        drawborder    =-108
        displaybeep   =-96
        closelibrary  =-414
        openlib       =-408
        execbase      = 4
        getmsg        =-372

        joy2          =$dff0c
        fire          =$bfe001

        ;!!!when > 500kb !!!
        ;org $40000
        ;load $40000
        ; or use AssemPro to place in CHIP RAM
        ;!!!!!!!!!!!!!!!!!!!!!!!

        run:   
               bsr     openint
               bsr     scropen
               bsr     windopen
               bsr     setmenu
               bsr     print

               lea     border,a1
               move    #22,d0
               move    #30,d1
               bsr     borderdraw
              
               bsr     draw
               
               bsr     request

        loop:
               move.l  execbase,a6
               move.l  windowhd,a0
               move.l  86(a0),a0        ;user port
               jsr     getmsg(a6)
               tst.l   d0
               beq     loop             ;no event
               move.l  d0,a0
               move.l  $16(a0),msg      ;event:LO=item,HI=Event
               move.l  msg,d6           ;to test
               move.l  d6,d7
               lsr     #8,d7
               lsr     #3,d7            ;sub menu point in D7
               clr.l   d5
               roxr    #1,d6
               roxl    #1,d5            ;menu number in D5
               and.l   #$7f,d6
               cmp     #$7f,d6          ;no menu point?
               beq     loop             ;no:continue
               lsr     #4,d6            ;menu point in D6
               cmp     #1,d6            ;point 2?
               bne     no1
               move,l  intbase,a6
               move.l  screenhd,a0
               jsr     displaybeep(a6)

        no1:
               cmp     #0,d6
               bne     loop

        ende:
               bsr     clearmenu
               bsr     windclose
               bsr     scrclose
               bsr     closeint
               rts

        openint:
               move.l  execbase,a6
               lea     intname,a1
               jsr     openlib(a6)
               move.l  d0,intbase
               rts

        closeint:
               move.l  execbase,a6
               move.l  intbase,a1
               jsr     closelibrary(a6)
               rts

        scropen:
               move.l  inbase,a6
               lea     screen_defs,a0
               jsr     openscreen(a6)
               move.l  d0,screenhd

        scrclose:
               move.l  inbase,a6
               move.l  screenhd,a0
               jsr     closescreen(a6)
               rts

        scrmove:
               move.l  intbase,a6
               move,l  screenhd,a0
               jsr     movescreen(a6)
               rts

        windopen:
               move.l  intbase,a6
               lea     windowdef,a0
               jsr     openwindow(a6)
               move.l  d0,windowhd
               rts

        windclose:
               move.l  intbase,a6
               move.l  windowhd,a0
               jsr     closewindow(a6)
               rts

        request:
               move.l  windowhd,a0
               lea     btext,a1
               lea     ltext,a2
               lea     rtext,a3
               move.l  #0,d0
               move.l  #0,d1
               move.l  #180,d2
               move.l  #80,d3
               move.l  intbase,a6
               jsr     autorequest(a6)
               rts

        setmenu:
               lea     mentab,a0        ;pointer to text pointer in A0
               lea     menu,a1          ;pointer to menu field in A1
               move    #10,d1           ;menu position = 10

        menuloop:
               clr.l   d2               ;menu point-Y=0
               move.l  a1,a2            ;save pointer
               tst.l   (a0)
               beq     setmenu1         ;end
               clr.l   (a1)+
               move    d1,(a1)+
               add.l   #70,d1
               move.l  #50,(a1)+
               move.l  #$a0001,(a1)+
               move.l  (a0)+,(a1)+      ;menu title
               lea     12(a1),a3
               move.l  a3,(a1)+         ;menu point
               clr.l   (a1)+
               clr.l   (a1)+

        itemloop:
               tst.l   (a0)             ;last one?
               beq     menuend          ;yes
               lea     54(a1),a3
               move.l  a3,(a1)+         ;pointer to next point
               move.l  d2,(a1)+         ;X/Y
               add     #10,d2
               move.l  #$5a000a,(a1)+   ;width/height
               move    #$52,(a1)+
               clr.l   (a1)+
               lea     16(a1),a3
               move.l  a3,(a1)+         ;text structor-pointer
               clr.l   (a1)+
               clr.l   (a1)+
               clr.l   (a1)+

               move    #$1,(a1)+        ;text-structor set
               clr     (a1)+
               move.l  #$50003,(a1)+
               clr.l   (a1)+
               move.l  (a0)+,(a1)+      ;text pointer
               clr.l   (a1)+

               bra     itemloop         ;next point...

        menuend:
               clr.l   -54(a1)
               tst.l   (a0)+
               tst.l   (a0)             ;still in menu?
               beq     setmenu1         ;no:ready
               move.l  a1,(a2)          ;pointer to next menu
               bra     menuloop         ;and continue

        setmenu1:
               move.l  intbase,a6
               move.l  windowhd,a0
               lea     menu,a1
               jsr     setmenustrip(a6)
               rts

        clearmenu:
               move.l  intbase,a6
               move.l  windowhd,a0
               jsr     clearmenustrip(a6)
               rts

        print:
               move.l  intbase,a6
               move.l  windowhd,a0
               move.l  50(a0),a0
               lea     ggtext,a1
               move.l  #30,d0           ;X
               move.l  #16,d1           ;Y
               jsr     printitext(a6)
               rts

        draw:
               move.l  intbase,a6
               move.l  windowhd,a0
               move.l  50(a0),a0
               lea     image,a1
               move.l  #200,d0
               move.l  #100,d1
               jsr     drawimage(a6)
               rts

        borderdraw:
               move.l  intbase,a6
               move.l  windowhd,a0
               move.l  50(a0),a0
               jsr     drawborder(a6)
               rts

        screen_defs:
               dc.w  0,0
               dc.w  640,200
               dc.w  4
               dc.b  0
               dc.b  1
               dc.w  $800
               dc.w  15
               dc.l  0
               dc.l  tite1
               dc.l  0
               dc.l  0

        windowdef:
               dc.w  10,20
               dc.w  300,150
               dc.b  0,1
               dc.l  $300
               dc.l  $100f
               dc.l  gadget
               dc.l  0
               dc.l  windname

        screenhd:
               dc.l  0
               dc.l  0 
               dc.w  200,40,600,200
               dc.w  $f

        btext:
               dc.b  3,3
               dc.b  0
               align
               dc.w  10,10
               dc.l  0
               dc.l  bodytxt
               dc.l  0
      
        bodytxt:dc.b  "Requester-Text",0
               align

        ltext:
               dc.b  3,1
               dc.b  0
               align  dc.w 5,3
               dc.l  0
               dc.l  lefttext
               dc.l  0

        lefttext: dc.b "left",0
               align

        rtext:
               dc.b  0,1
               dc.b  0
               align  dc.w 5,3
               dc.l  0
               dc.l  righttext
               dc.l  0

        righttext: dc.b "right",0
               align
        tite1: dc.b  "User Screen",0
        windname: dc.b "Window-Title",0
               align  windowhd: dc.l 0

        intbase:dc.l  0
        intname:dc.b  "intuition.library",0
               align  msg:dc.l 0

        mentab:
               dc.l  menu1
               dc.l  mp11,np12,mp13,mp14,mp15,mp16,mp17,mp18,mp19,0
               dc.l  menu2
               dc.l  mp21,mp22,mp23,0
               dc.l  menu3
               dc.l  mp31,mp32,0
               dc.l  menu4,mp41,0
               dc.l  0

        menu1: dc.b  "Menu 1",0
        mp11:  dc.b  "Point 11",0
        mp12:  dc.b  "Point 12",0
        mp13:  dc.b  "Point 13",0
        mp14:  dc.b  "Point 14",0
        mp15:  dc.b  "Point 15",0
        mp16:  dc.b  "Point 16",0
        mp17:  dc.b  "Point 17",0
        mp18:  dc.b  "Point 18",0
        mp19:  dc.b  "Point 19",0

        menu2: dc.b  "Menu 2",0
        mp21:  dc.b  "End!",0
        mp22:  dc.b  "Beep",0
        mp23:  dc.b  "Point 23",0
  
        menu3: dc.b  "Menu 3",0
        mp31:  dc.b  "Point 31",0
        mp32:  dc.b  "Point 32",0

        menu4: dc.b  "Menu 4",0
        mp41:  dc.b  "Point 41",0
               align

        gadget:
               dc.l  gadget1
               dc.w  20,80,80,10
               dc.w  0
               dc.w  $2               ;activation,$802 for longint
               dc.w  4
               dc.l  border
               dc.l  0
               dc.l  0
               dc.l  0
               dc.l  strinfo
               dc.w  2
               dc.l  0

        border:
               dc.w  0,0
               dc.b  1,0,0
               dc.d  5               ;XY-pair
               dc.l  koord
               dc.l  0

        koord:
               dc.w  -2,-2,80,-2,80,9,-2,9,-2,-2

        strinfo:
               dc.l  strpuffer
               dc.l  undo
               dc.w  0               ;cursor position
               dc.w  10              ;max.char
               dc.w  0  
               dc.w  0,0,0,0,0
               dc.l  0,0,0

        strpuffer:
               dc.b  "Hello!",0,0,0
        
        undo:  dc.l  0,0,0
               align

        gadget1:
               dc.l  gadget2           ;more gadget
               dc.w  40,50,32,13
               dc.w  $6                ;flags:invert
               dc.w  $103              ;activate
               dc.w  1                 ;gadget type
               dc.l  image             ;gadget image
               dc.l  image2            ;select gadget
               dc.l  ggtext            ;gadget text
               dc.l  0                 ;no exclude
               dc.l  0                 ;special info
               dc.w  1                 ;ID
               dc.l  0                 ;user data

        ggtext:
               dc.b  1,0,1
               align
               dc.w  -8,14
               dc.l  0
               dc.l  swtext
               dc,l  0
       
        swtext:
               dc.b  "Switch",0
               align

        image:
               dc.w  0,0
               dc.w  32,13
               dc.w  1
               dc.l  imgdata
               dc.b  2,1
               dc.l  0

        image2:
               dc.w  0,0
               dc.w  32,13
               dc.w  1
               dc.l  imgdata2
               dc.b  2,1
               dc.l  0

        imgdata:
               dc.l 0
               dc.l %00000000011100000000000000000000
               dc.l %00000000111110000011101001000000
               dc.l %00000000111110000010101101000000
               dc.l %00000000011110000010101011000000
               dc.l %00000000000111000011101001000000
               dc.l %00000000000011100000000000000000
               dc.l %00000000000001110000000000000000
               dc.l %00000000000111111111100000000000
               dc.l %00000000001111111111110000000000
               dc.l %00000000001111111111110000000000
               dc.l %00000000000110000001100000000000
               dc.l 0

        imgdata2:
               dc.l 0
               dc.l %00000000000000000000111000000000
               dc.l %00011101110111000001111100000000
               dc.l %00010101000100000001111100000000
               dc.l %00010101100110000001111000000000
               dc.l %00011101000100000011100000000000
               dc.l %00000000000000000111000000000000
               dc.l %00000000000000001110000000000000
               dc.l %00000000000111111111100000000000
               dc.l %00000000001111111111110000000000
               dc.l %00000000001111111111110000000000
               dc.l %00000000000110000001100000000000
               dc.l 0

        gadget2:
               dc.l  0
               dc.w  150,30,100,50
               dc.w  5
               dc.w  2
               dc.w  3                   ;prop.gadet
               dc.l  mover               ;border
               dc.l  0,0,0
               dc.l  specinfo
               dc.w  3
               dc.l  0

        specinfo:
               dc.w  6                   ;flags:free horiz
               dc.w  0,0
               dc.w  $ffff/10,$ffff/5
               dc.w  0,0,0,0,0,0

        mover:
               dc.w  0,0,16,7
               dc.w  1
               dc.l  moverdata
               dc.b  1,0
               dc.l  0

        moverdata:
               dc.w %0111111111111110
               dc.w %0101111111111010
               dc.w %0101011111101010
               dc.w %0101010110101010
               dc.w %0101011111101010
               dc.w %0101111111111010
               dc.w %0111111111111110

        menu:blk.w  500

               end
               
               


      Chapter 8.
      ----------
      8.Advanced Programming.
      -----------------------
        You've learned a lot about machine language programming on the
        Amiga.What you need yet are a few routines that can be used as
        programming tools.We'll work on that right now.They'll be easy to 
        use in your own program.The sky's the limit now!

      8.1.Supervisor Mode.
      --------------------
        As mentioned in the chapter on the MC68000 processor,there are two
        operating modes:the User and the Supervisor mode.It is often
        necessary to move between the two modes.However,this isn't a
        simple process.
        The reason you want to do this,is that in User mode,you can't
        access the Status register.If you write to one of them,an
        Exception is executed which crashes the program.

        How can you get in Supervisor mode?

        No problem.The operating system of the Amiga contains a function
        in the EXEC library that lets you get into supervisor mode.Its
        called SuperState and it doesn't need any parameters.You can
        easily call this program by using the following lines:

        execbase    = 4                 ;exec base address
        superstate  =-150               ;turn on function
               ...
               move.l  execbase,a6      ;exec base address in A6
               jsr     superstate(a6)   ;turn on supervisor mode
               move.l  d0,savesp        ;save return value
               ...
        savesp:blk.l   1                ;space for sp value

        You get the value of the Stack Pointer(SP)back in the D0 register.
        You'll also find it in register A7,but this register is changed   
        regularly.The reason is that in Supervisor mode,the Amiga works
        with all the Interrupts and with the SP,and there are lots of     
        Interrupts for this computor.We'll talk about interrupts in a bit.

        After this call,you'll use the user stack instead of the
        supervisor stack.In this way,you can access the old user stack.You
        need to make sure that the user stack is large enough since the   
        interrupts must have enough room for their data on the stack.
        You need to save the value returned in D0,because you'll need this
        value later.You need to return to user mode sometime.Theres a
        function for this in the exec library as well.It is called the    
        UserState function.It needs one parameter,the SP value that comes 
        back from the SuperState function.
        Since you've saved this value in the long word starting at
        "savesp",you can write the following:

        userstate     =-156
               ...
               move.l  execbase,a6      ;exec base address in A6
               move.l  savesp,d0        ;put old sp in D0
               jsr     userstate(a6)    ;return to user mode

        Now you are back in the user mode.The user stack point(USP)is the 
        same as before.You can write functions that need to be run from
        the supervisor mode as subroutines.First you call superstate,save 
        the return value,execute the desired function,call userstate,and  
        end with a RTS command.If the USP was changed,the RTS command     
        would'nt work right,and the computor would jump who knows where
        and perhaps crash.Here it works though.
        Now comes the question:how does the operating system get the
        supervisor mode?Thats not too difficult;it goes like this:

        The superstate function attempts to access a Status Register.This 
        causes an Exception to occur and a routine is called whose address
        begins at the long word starting at $20.It is the Exception Vector
        for Privilege Violation.The routine that it branches to is called 
        in supervisor mode.Then it tests where this exception came from.If
        the routine finds that the exception comes from the superstate    
        routine whose address it knows,the matter is settled.It just
        branches to the routine without turning off the user mode.Thats
        all there is to it.

      8.2.Exception Programming.
      --------------------------
        The exceptions described in the processor chapter offer you a lot 
        of oppertunities to control the Amiga's functions.You can use them
        to specify how errors should be handled and even list a crash
        program.

        Here is a list of vectors that are used to jump to the exception  
        routines:

        Number      Address          Use with
        ------------------------------------------------------------------
          2         $008             Bus error
          3         $00C             Address eror
          4         $010             Illegal command
          5         $014             Division by zero
          6         $018             CHK command
          7         $01C             TRAPV command
          8         $020             Privilege Violation
          9         $024             Trace
         10         $028             Axxx command emulation
         11         $02C             Fxxx command emulation
                    $030-$038        Reserved
         15         $03C             Uninitialized interrupt
                    $040-$05F        Reserved
         24         $060             Unauthorised interrupt
        25-31       $064-$083        Level 1-7 interrupt
        32-47       $080-$0BF        TRAP commands
                    $0C0-$0FF        Reserved
        64-255      $100-$3FF        User interrupt vector

        Lets look at the TRAP commands as an example.They aren't used in
        the Amiga operating system.A TRAP command and a number between
        zero and fifteen are used to call one of the 16 posible TRAP
        routines.If the command TRAP #0 is executed,the processor (in
        supervisor mode)branches to the routine whose address lies at $80 
        in memory.This routine must end with a RTE(ReTurn from Exception) 
        command.
        Some operating systems,for example,the ATARI ST's TOS operating   
        systems,are completely callable via these TRAP's.Parameters are
        put on the stack,and then a TRAP command is executed.The advantage
        is that you don't have to know any of the operating systems
        addresses.In the Amiga you must know the addresses(Execbase=4).

        Lets write your own TRAP routine to demonstrate the use of the
        TRAP command.You'll need three program sections:

        1.The initialization of the TRAP vector.
        2.The TRAP routine itself(It must end with RTE).
        3.A test routine that calls the TRAP command.

        Initialization is very short:

        init:
               move.l  #trap0,$80        ;set vector for TRAP #0
               rts

        Now you need to write the trap0 routine.Lets use the example from 
        the hardware chapter that produced a beep.
        Lets write this routine using as little effort as possible.Change 
        the RTS to a RTE at the end,erase the line in which the loop
        counter D0 was loaded for the tone production,and change the loop 
        so that it works with long words.Now you can load the register
        with an arbitrary value and have the TRAP #0 followed by a peep of
        arbitrary duration.

        ;** beep tone production after a TRAP #0 **

        ctlw   =$dff096                  ;DMA control
        c0thi  =$dff0a0                  ;HI table address
        c0tlo  =c0thi+2                  ;LO table address
        c0tl   =c0thi+4                  ;table length
        c0per  =c0thi+6                  ;read in rate
        c0vol  =c0thi+8                  ;volume

        trap0:                           ;* produce a short peep
               move.l  #table,c0thi      ;table beginning
               move    #4,c0tl           ;table length
               move    #300,c0per        ;read in rate
               move    #40,c0vol         ;volume
               move    #$8201,ctlw       ;start DMA (sound)

        loop:
               subq.l  #1,d0             ;counter -1
               bne     loop              ;count dwn to zero

        still:
               move    #1,ctlw           ;turn on tone
               rte                       ;exception end

        table:                           ;sound table
               dc.b    -40,-70,-40,0,40,70,40,0

        You need to make sure that "table"is in CHIP RAM($00000-$7FFFF),
        otherwise the sound chip can't access the data!

        After entering this,you can test it out using the following
        routine:

        test:
               move.l  #$2ffff,d0        ;pass tone length in D0
               trap    #0                ;carry out exception:peep
               rts

        Now assemble both routines and start the initialization routine,  
        init.Nothing happens.
        Start the second routine,test.A beep that lasts about one second
        is output.
        One thing you must keep in mind is that if you change the program 
        and reassemble it,the address of the trap0 routine can change.    
        Before you execute the TRAP command,you must repeat the initializ-
        ation,so that the computor doesn't jump to the wrong location!               
        



      Appendices.
      -----------
      Overview of Library Functions.
      ------------------------------
        The following table gives you an overview of the available
        libraries and their functions.Each sublist of functions is
        preceded by the name of the library it is found in.
        These functions are listed with their negative offset in hex and  
        decimal.Their name and their parameters are also specified.The    
        parameter names are in parenthesis behind the function name.The   
        second set of parenthesis includes a list of registers that
        correspond to the parameter names.If no parameters are needed,we  
        put () to let you know.

 CLIST.LIBRARY
  -$001E  -30             InitCLPool (cLPool,size) (A0,D0)
  -$0024  -36             AllocCList (cLPool) (A1)
  -$002A  -42             FreeCList (cList) (A0)
  -$0030  -48             FlushCList (cList) (A0)
  -$0036  -54             SizeCList (cList) (A0)
  -$003C  -60             PutCLChar (cList,byte) (A0,D0)
  -$0042  -66             GetCLChar (cList) (A0)
  -$0048  -72             UnGetCLChar (cList,byte) (A0,D0)
  -$004E  -78             UpPutCLChar (cList) (A0)
  -$0054  -84             PutCLWord (cList,word) (A0,D0)
  -$005A  -90             GetCLWord (cList) (A0)
  -$0060  -96             UnGetCLWord (cList,word) (A0,D0)
  -$0066  -102            UnPutCLWord (cList) (A0)
  -$006C  -108            PutCLBuf (cList,buffer,length) (A0,A1,D1)
  -$0072  -114            GetCLBuf (cList,buffer,maxLength) (A0,A1,D1)
  -$0078  -120            MarkCList (cList,offset) (A0,D0)
  -$007E  -126            IncrCLMark (cList) (A0)
  -$0084  -132            PeekCLMark (cList) (A0)
  -$008A  -138            SplitCList (cList) (A0)
  -$0090  -144            CopyCList (cList) (A0)
  -$0096  -150            SubCList (cList,index,length) (A0,D0.D1)
  -$009C  -156            ConcatCList (sourceCList,destCList) (A0,A1)

 CONSOLE.LIBRARY
  -$002A  -42             CDInputHandler (events,device) (A0,A1)
  -$0030  -48             RawKeyConvert (events,buffer,length,keyMap)
                                        (A0,A1,D1,A2)
 DISKFONT.LIBRARY
  -$001E  -30             OpenDiskFont (textAttr) (A0)
  -$0024  -36             AvailFonts (buffer,bufBytes,flags) (A0,D0,D1)

 DOS.LIBRARY
  -$001e   -30            Open (name,access mode)(d1,d2)
  -$0024   -36            Close (file)(d1)
  -$002a   -42            Read (file,buffer,length)(d1,d2,d3)
  -$0030   -48            Write (file,buffer,length)(d1,d2,d3)
  -$0036   -54            Input()
  -$003c   -60            Output()
  -$0042   -66            Seek(file,position,offset)(d1,d2,d3)
  -$0048   -72            DeleteFile (name)(d1)
  -$004e   -78            Rename(oldname,newname)(d1,d2)
  -$0054   -84            Lock(name,type)(d1,d2)
  -$005a   -90            UnLock(lock)(d1)
  -$0060   -96            DupLock(lock)(d1)
  -$0066   -102           Examine(lock,fileinfoblock)(d1,d2)
  -$006c   -108           ExNext(lock,fileinfoblock)(d1,d2)
  -$0072   -114           Info(lock,parameterblock)(d1,d2)
  -$0078   -120           CreateDir(name)(d1)
  -$007e   -126           CurrentDir(lock)(d1)
  -$0084   -132           IoErr()
  -$008a   -138           CreateProc(name,pri,seglist,stacksize)(d1,d2,d3,d4)
  -$0090   -144           Exit(returncode)(d1)
  -$0096   -150           LoadSeg(filename)(d1)
  -$009c   -156           UnLoadSeg(segment)(d1)
  -$00a2   -162           Getpacket(wait)(d1)
  -$00a8   -168           Queuepacket(packet)(d1)
  -$00ae   -174           DeviceProc(name)(d1)
  -$00be   -180           SetComment(name,comment)(d1,d2)
  -$ooba   -186           SetProtection(name,mask)(d1,d2)
  -$00c0   -192           DateStamp(date)(d1)
  -$00c6   -198           Delay(timeout)(d1)
  -$00cc   -204           WaitForChar(file,timeout)(d1,d2)
  -$00d2   -210           ParentDir(lock)(d1)
  -$00d8   -216           IsInteractive(file)(d1)
  -$00de   -222           Execute(string,file,file)(d1,d2,d3)

 EXEC.LIBRARY
  -$001e   -30            Supervisor()
  -$0024   -36            ExitIntr()
  -$002a   -42            Schedule()
  -$0030   -48            Reschedule()
  -$0036   -54            Switch()
  -$003c   -60            Dispatch()
  -$0042   -66            Exception()
  -$0048   -72            InitCode(startclass,version)(d0,d1)
  -$004e   -78            InitStruct(inittable,memory,size)(a1,a2,d0)
  -$0054   -84            MakeLibrary(funcinit,structinit,libinit,datasize,
                          codesize)(a0,a1,a2,d0,d1)
  -$005a   -90            MakeFunctions(target,functionarray,funcdispbase)
                          (a0,a1,a2)
  -$0060   -96            FindResident(name)(a1)
  -$0066   -102           InitResident(resident,seglist)(a1,d1)
  -$006c   -108           Alert(alertnum,parameters)(d7,a5)
  -$0072   -114           Debug()
  -$0078   -120           Disable()
  -$007e   -126           Enable()
  -$0084   -132           Forbid()
  -$008a   -138           Permit()
  -$0090   -144           SetSR(newsr,mask)(d0,d1)
  -$0096   -150           SuperState()
  -$009c   -156           UserState(sysstack)(d0)
  -$00a2   -162           setIntVector(intnumber,interrupt)(d0,d1)
  -$00a8   -168           AddIntServer(intnumber,interrupt)(d0,d1)
  -$00ae   -174           RemIntServer(intnumber,interrupt)(d0,d1)
  -$00b4   -180           Cause(interrup)(a1)
  -$00ba   -186           Allocate(freelist,bytesize)(a0,d0)
  -$00c0   -192           Deallocate(freelist,memoryblock,bytesize)(a0,a1,d0)
  -$00c6   -198           AllocMem(bytesize,requirements)(d0,d1)
  -$00cc   -204           AlloAbs(bytesize,location)(d0,a1)
  -$00d2   -210           FreeMem(memoryblock,bytesize)(a1,d0)
  -$00d8   -216           AvailMem(requirements)(d1)
  -$00de   -222           AllocEntry(entry)(a0)
  -$00e4   -228           FreeEntry(entry)(a0)
  -$00ea   -234           Insert(list,node,pred)(a0,a1,a2)
  -$00f0   -240           AddHead(list,node)(a0,a1)
  -$00f6   -246           AddTail(list,node)(a0,a1)
  -$00fc   -252           Remove(node)(a1)
  -$0102   -258           RemHead(list)(a0)
  -$0108   -264           RemTail(list)(a0)
  -$010e   -270           Enqueue(list,node)(a0,a1)
  -$0114   -276           FindName(list,name)(a0,a1)
  -$011a   -282           AddTask(task,initpc,finalpc)(a1,a2,a3)
  -$0120   -288           RemTask(task)(a1)
  -$0126   -294           FindTask(name)(a1)
  -$012c   -300           SetTaskPri(task,prority)(a1,d0)
  -$0132   -306           SetSignal(newsignals,signelset)(d0,d1)
  -$0138   -312           SetExcept(newsignals,signalset)(d0,d1)
  -$013e   -318           Wait(signalset)(d0)
  -$0144   -324           Signal(task,signalset)(a1,d0)
  -$014a   -330           AllocSignal(signalnum)(d0)
  -$0150   -336           FreeSignal(signalnum)(d0)
  -$0156   -342           AllocTrap(trapnum)(d0)
  -$015c   -348           FreeTrap(trapnum)(d0)
  -$0162   -354           AddPort(port)(a1)
  -$0168   -360           RemPort(port)(a1)
  -$016e   -366           PutMsg(port,message)(a0,a1)
  -$0174   -372           GetMsg(port)(a0)
  -$017a   -378           ReplyMsg(message)(a1)
  -$0180   -384           WaitPort(port)(a0)
  -$0186   -390           FindPort(name)(a1)
  -$018c   -396           AddLibrary(library)(a1)
  -$0192   -402           RemLibrary(library)(a1)
  -$0198   -408           OldOpenLibrary(libname)(a1)
  -$019e   -414           CloseLibrary(library)(a1)
  -$01a4   -420           Setfunction(library,funcoffset,funcentry)(a1,a0,d0)
  -$01aa   -426           SumLibrary(library)(a1)
  -$01b0   -432           AddDevice(device)(a1)
  -$01b6   -438           RemDevice(device)(a1)
  -$01bc   -444           OpenDevice(devname,unit,iorequest,flags)(a0,d0,a1
                          ,d1)
  -$01c2   -450           CloseDevice(iorequest)(a1)
  -$01c8   -456           DoIO(iorequest)(a1)
  -$01ce   -462           SendIO(iorequest)(a1)
  -$01d4   -468           CheckIO(iorequest)(a1)
  -$01da   -474           WaitIO(iorequest)(a1)
  -$01e0   -480           AbortIO(iorequest)(a1)
  -$01e6   -486           AddResource(resource)(a1)
  -$01ec   -492           RemResource(resource)(a1)
  -$01f2   -498           OpenResource(resname,version)(a1,d0)
  -$01f8   -504           RawIOInit()
  -$01fe   -510           RawMayGetChar()
  -$0204   -516           RawPutChar(char)(d0)
  -$020a   -522           RawDoFmt()(a0,a1,a2,a3)
  -$0210   -528           GetCC()
  -$0216   -534           TypeOfMem(address)(a1)
  -$021c   -540           Procedure(semaport,bidmsg)(a0,a1)
  -$0222   -546           Vacate(semaport)(a0)
  -$0228   -552           OpenLibrary(libname,version)(a1,d0)

 GRAPHICS.LIBRARY
  -$001e   -30            BltBitMap(scrbitmap,scrx,scry,destbitmap,destx,
                          desty,sizex,sizey,minterm,mask,tempa)
                          (a0,d0,d1,a1,d2,d3,d4,d5,d6,d7,a2)
  -$0024   -36            BltTemplate(source,scrx,scrmod,destrastport,destx,
                          desty,sixex,sizey)(a0,d0,d1,a1,d2,d3,d4,d5)
  -$002a   -42            ClearEOL(rastport)(a1)
  -$0030   -48            ClearScreen(rastport)(a1)
  -$0036   -54            TextLength(rastport,string,count)(a1,a0,d0)
  -$003c   -60            Text(rastport,string,count)(a1,a0,d0)
  -$0042   -66            SetFont(rastportid,textfont)(a1,a0)
  -$0048   -72            OpenFont(textattr)(a0)
  -$004e   -78            CloseFont(textfont)(a1)
  -$0054   -84            AskSoftStyle(rastport)(a1)
  -$005a   -90            SetSoftStyle(rastport,style,enable)(a1,d0,d1)
  -$0060   -96            AddBob(bob,rastport)(a0,a1)
  -$0066   -102           AddVSprite(vsprite,rastport)(a0,a1)
  -$006c   -108           DoCollision(rastport)(a1)
  -$0072   -114           DrawGList(rastport,viewport)(a1,a0)
  -$0078   -120           InitGels(dummyhead,dummytail,gelsinfo)(a0,a1,a2)
  -$007e   -126           InitMasks(vsprite)(a0)
  -$0084   -132           RemIBob(bob,rastport,viewport)(a0,a1,a2)
  -$008a   -138           RemVSprite(vsprite)(a0)
  -$0090   -144           SetCollision(type,routine,gelsinfo)(d0,a0,a1)
  -$0096   -150           SortGList(rastport)(a1)
  -$009c   -156           AddAnimObj(obj,animationkey,rastport)(a0,a1,a2)
  -$00a2   -162           Animate(animationkey,rastport)(a0,a1)
  -$00a8   -168           etGBuffers(animationobj,rastport,doublebuffer)(a0,
                          a1,d0)
  -$00ae   -174           InitGMasks(animationobj)(a0)
  -$00b4   -180           GelsFuncE()
  -$00ba   -186           GelsFuncF()
  -$00c0   -192           LoadRGB4(viewport,colurs,count)(a0,a1,d0)
  -$00c6   -198           InitRastPort(rastport)(a1)
  -$00cc   -204           InitVPort(viewport)(a0)
  -$00d2   -210           MrgCop(view)(a1)        
  -$00D8  -216            MakeVPort (view,viewPort) (A0,A1)
  -$00DE  -222            LoadView (view) (A1)
  -$00E4  -228            WaitBlit ()
  -$00EA  -234            SetRast (rastPort,color) (A1,D0)
  -$00F0  -240            Move (rastPort,x,y) (A1,D0,D1)
  -$00F6  -246            Draw (rastPort,x,y) (A1,D0,D1)
  -$00FC  -252            AreaMove (rastPort,x,y) (A1,D0,D1)
  -$0102  -258            AreaDraw (rastPort,x,y) (A1,D0,D1)
  -$0108  -264            AreaEnd (rastPort) (A1)
  -$010E  -270            WaitTOF ()
  -$0114  -276            QBlit (blit) (A1)
  -$011A  -282            InitArea (areaInfo,vectorTable,vectorTableSize)
                          (A0,A1,D0)
  -$0120  -288            SetRGB4 (viewPort,index,r,g,b) (A0,D0,D1,D2,D3)
  -$0126  -294            QBSBlit (blit) (A1)
  -$012C  -300            BltClear (memory,size,flags) (A1,D0,D1)
  -$0132  -306            RectFill (rastPort,xl,yl,xu,yu)
                          (A1,D0,D1,D2,D3)
  -$0138  -312            BltPattern (rastPort,ras,xl,yl,maxX,maxY,
                          fillBytes) (A1,A0,D0,D1,D2,D3,D4)
  -$013E  -318            ReadPixel (rastPort,x,y) (A1,D0,D1)
  -$0144  -324            WritePixel (rastPort,x,y) (A1,D0,D1)
  -$014A  -330            Flood (rastPort,mode,x,y) (A1,D2,D0,D1)
  -$0150  -336            PolyDraw (rastPort,count,polyTable) (A1,D0,A0)
  -$0156  -342            SetAPen (rastPort,pen) (A1,D0)
  -$015C  -348            SetBPen (rastPort,pen) (A1,D0)
  -$0162  -354            SetDrMd (rastPort,drawMode) (A1,D0)
  -$0168  -360            InitView (view) (A1)
  -$016E  -366            CBump (copperList) (A1)
  -$0174  -372            CMove (copperList,destination,data) (A1,D0,D1)
  -$017A  -378            CWait (copperList,x,y) (A1,D0,D10
  -$0180  -384            VBeamPos ()
  -$0186  -390            InitBitMap (bitMap,depth,width,height)
                          (A0,D0,D1,D2)
  -$018C  -396            ScrollRaster (rastPort,dX,dY,minx,miny,maxx,
                          maxy) (A1,D0,D1,D2,D3,D4,D5)
  -$0192  -402            WaitBOVP (viewPort) (A0)
  -$0198  -408            GetSprite (simpleSprite,num) (A0,D0)
  -$019E  -414            FreeSprite (num) (D0)
  -$01A4  -420            ChangeSprite (vp,simpleSprite,data) (A0,A1,A2)
  -$01AA  -426            MoveSprite (viewPort,simpleSprite,x,y)
                          (A0,A1,D0,D1)
  -$01B0  -432            LockLayerRom (layer) (A5)
  -$01B6  -438            UnlockLayerRom (layer) (A5)
  -$01BC  -444            SyncSBitMap (1) (A0)
  -$01C2  -450            CopySBitMap (11,12) (A0,A1)
  -$01C8  -456            OwnBlitter ()
  -$01CE  -462            DisownBlitter ()
  -$01D4  -468            InitTmpRas (tmpras,buff,size) (A0,A1,D0)
  -$01DA  -474            AskFont (rastPort,textAttr) (A1,A0)
  -$01E0  -480            AddFont (textFont) (A1)
  -$01E6  -486            RemFont (textFont) (A1)
  -$01EC  -492            AllocRaster (width,height) (D0,D1)
  -$01F2  -498            FreeRaster (planeptr,width,height) (A0,D0,D1)
  -$01F8  -504            AndRectRegion (rgn,rect) (A0,A1)
  -$01FE  -510            OrRectRegion (rgn,rect) (A0,A1)
  -$0204  -516            NewRegion ()
  -$020A  -522            ** reserved **
  -$0210  -528            ClearRegion (rgn) (A0)
  -$0216  -534            DisposeRegion (rgn) (A0)
  -$021C  -540            FreeVPortCopLists (viewPort) (A0)
  -$0222  -546            FreeCopList (coplist) (A0)
  -$0228  -552            ClipBlit (srcrp,srcX,srcY,destrp,destX,destY,
                          sizeX,sizeY,minterm) (A0,D0,D1,A1,D2,D3,D4,D5,D6)
  -$022E  -558            XorRectRegion (rgn,rect) (A0,A1)
  -$0234  -564            FreeCprList (cprlist) (A0)
  -$023A  -570            GetColorMap (entries) (D0)
  -$0240  -576            FreeColorMap (colormap) (A0)
  -$0246  -582            GetRGB4 (colormap,entry) (A0,D0)
  -$024C  -588            ScrollVPort (vp) (A0)
  -$0252  -594            UCopperListInit (copperlist,num) (A0,D0)
  -$0258  -600            FreeGBuffers (animationObj,rastPort,
                          doubleBuffer) (A0,A1,D0)
  -$025E  -606            BltBitMapRastPort (srcbm,srcx,srcy,destrp,
                          destX,destY,sizeX,sizeY,minter)
                          (A0,D0,D1,A1,D2,D3,D4,D5,D6)

 ICON.LIBRARY
  -$001E  -30             GetWBObject (name) (A0)
  -$0024  -36             PutWBObject (name,object) (A0,A1)
  -$002A  -42             GetIcon (name,icon,freelist) (A0,A1,A2)
  -$0030  -48             PutIcon (name,icon) (A0,A1)
  -$0036  -54             FreeFreeList (freelist) (A0)
  -$003C  -60             FreeWBOject (WBOject) (A0)
  -$0042  -66             AllocWBOject ()
  -$0048  -72             AddFreeList (freelist,mem,size) (A0,A1,A2)
  -$004E  -78             GetDiskObject (name) (A0)
  -$0054  -84             PutDiskObject (name,diskobj) (A0,A1)
  -$005A  -90             FreeDiskObj (diskobj) (A0)
  -$0060  -96             FindToolType (toolTypeArray,typeName) (A0.A1)
  -$0066  -102            MatchToolValue (typeString,value) (A0,A1)
  -$006C  -108            BumbRevision (newname,oldname) (A0,A1)

 INTUITION.LIBRARY
  -$001E  -30             OpenIntuition ()
  -$0024  -36             Intuition (ievent) (A0)
  -$002A  -42             AddGadget (AddPtr,Gadget,Position) (A0,A1,D0)
  -$0030  -48             ClearDMRequest (Window) (A0)
  -$0036  -54             ClearMenuStrip (Window) (A0)
  -$003C  -60             ClearPointer (Window) (A0)
  -$0042  -66             CloseScreen (Screen) (A0)
  -$0048  -72             CloseWindow (Window) (A0)
  -$004E  -78             CloseWorkbench ()
  -$0054  -84             CurrentTime (Seconds,Micros) (A0,A1)
  -$005A  -90             DisplayAlert (AlertNumber,String,Height)
                          (D0,A0,D1)
  -$0060  -96             DiplayBeep (Screen) (A0)
  -$0066  -102            DoubleClick (sseconds,smicros,cseconds,
                          cmicros) (D0,D1,D2,D3)
  -$006C  -108            DrawBorder (Rport,Border,LeftOffset,TopOffset)
                          (A0,A1,D0,D1)
  -$0072  -114            DrawImage (RPort,Image,LeftOffset,TopOffset)
                          (A0,A1,D0,D1)
  -$0078  -120            EndRequest (requester,window) (A0,A1)
  -$007E  -126            GetDefPref (preferences,size) (A0,D0)
  -$0084  -132            GetPrefs (preferences,size) (A0,D0)
  -$008A  -138            InitRequester (req) (A0)
  -$0090  -144            ItemAddress (MenuStrip,MenuNumber) (A0,D0)
  -$0096  -150            ModifyIDCMP (Window,Flags) (A0,D0)
  -$009C  -156            ModifyProp (Gadget,Ptr,Reg,Flags,HPos,VPos,
                          HBody,VBody) (A0,A1,A2,D0,D1,D2,D3,D4)
  -$00A2  -162            MoveScreen (Screen,dx,dy) (A0,D0,D1)
  -$00A8  -168            MoveWindow (Window,dx,dy) (A0,D0,D1)
  -$00AE  -174            OffGadget (Gadget,Ptr,Req) (A0,A1,A2)
  -$00B4  -180            OffMenu (Window,MenuNumber) (A0,D0)
  -$00BA  -186            OnGadget (Gadget,Ptr,Req) (A0,A1,A2)
  -$00C0  -192            OnMenu (Window,MenuNumber) (A0,D0)
  -$00C6  -198            OpenScreen (OSArgs) (A0)
  -$00CC  -204            OpenWindow (OWArgs) (A0)
  -$00D2  -210            OpenWorkBench ()
  -$00D8  -216            PrintIText (rp,itext,left,top) (A0,A1,D0,D1)
  -$00DE  -222            RefreshGadgets (Gadgets,Ptr,Req) (A0,A1,A2)
  -$00E4  -228            RemoveGadgets (RemPtr,Gadget) (A0,A1)
  -$00EA  -234            ReportMouse (Window,Boolean) (A0,D0)
  -$00F0  -240            Request (Requester,Window) (A0,A1)
  -$00F6  -246            ScreenToBack (Screen) (A0)
  -$00FC  -252            SCreenToFront (Screen) (A0)
  -$0102  -258            SetDMRequest (Window,req) (A0,A1)
  -$0108  -264            SetMenuStrip (Window,Menu) (A0,A1)
  -$010E  -270            SetPointer (Window,Pointer,Height,Width,
                          XOFFset, YOFFset) (A0,A1,D0,D1,D2,D3)
  -$0114  -276            SetWindowTitles (Window,windowTitle,
                          screenTitle) (A0,A1,A2)
  -$011A  -282            ShowTitle (Screen,ShowIt) (A0,D0)
  -$0120  -288            SizeWindow (Windowmdx,dy) (A0,D0,D1)
  -$0126  -294            ViewAddress ()
  -$012C  -300            ViewPortAddress (Window) (A0)
  -$0132  -306            WindowToBack (Window) (A0)
  -$0138  -312            WindowToFront (Window) (A0)
  -$013E  -318            WindowLimits (Window,minwidth,minheight,
                          maxwidth, maxheight) (A0,D0,D1,D2,D3)
  -$0144  -324            SetPrefs (preferences,size,flag) (A0,D0,D1)
  -$014A  -330            IntuiTextLength (itext) (A0)
  -$0150  -336            WBenchToBack ()
  -$0156  -342            WBenchToFront ()
  -$015C  -348            AutoRequest (Window,Body,PText,NText,PFlag,
                          NFlag,W,H) (A0,A1,A2,A3,D0,D1,D2,D3)
  -$0162  -354            BeginRefresh (Window) (A0)
  -$0168  -360            BuildSysRequest (Window,Body,PosText,NegText,
                          Flags,W,H) (A0,A1,A2,A3,D0,D1,D2)
  -$016E  -366            EndRefresh (Window,Complete) (A0,D0)
  -$0174  -372            FreeSysRequest (Window) (A0)
  -$017A  -378            MakeScreen (Screen) (A0)
  -$0180  -384            RemakeDisplay ()
  -$0186  -390            RethinkDisplay ()
  -$018C  -396            AllocRemember (RememberKey,Size,Flags) (A0,D0,D1)
  -$0192  -402            AlohaWorkBench (wbport) (A0)
  -$0198  -408            FreeRemember (RememberKey,ReallyForgot) (A0,D0)
  -$019E  -414            LockIBase (dontknow) (D0)
  -$01A4  -420            UnlockIBase (IBLock) (A0)

 LAYERS.LIBRARY
  -$001E  -30             InitLayers (li) (A0)
  -$0024  -36             CreateUpfrontLayer (li,bm,x0,y0,xl,yl,flags,
                          bm2) A0,A1,D0,D1,D2,D3,D4,A2)
  -$002A  -42             CreateBehindLayer (li,bm,x0,y0,xl,yl,flags,
                          bm2) (A0,A1,D0,D1,D2,D3,D3,A2)
  -$0030  -48             UpfrontLayer (li,layer) (A0,A1)
  -$0036  -54             BehindLayer (li,layer) (A0,A1)
  -$003C  -60             MoveLayer (li,layer,dx,dy) (A0,A1,D0,D1)
  -$0042  -66             SizeLayer (li,layer,dx,dy) (A0,A1,D0,D1)
  -$0048  -72             ScrollLayer (li,layer,dx,dy) (A0,A1,D0,D1)
  -$004E  -78             BeginUpdate (layer) (A0)
  -$0054  -84             EndUpdate (layer) (A0)
  -$005A  -90             DeleteLayer (li,layer) (A0,A1)
  -$0060  -96             LockLayer (li,layer) (A0,A1)
  -$0066  -102            UnlockLayer (li,layer) (A0,A1)
  -$006C  -108            LockLayers (li) (A0)
  -$0072  -114            UnlockLayers (li) (A0)
  -$0078  -120            LockLayerInfo (li) (A0)
  -$007E  -126            SwapBitRastPortClipRect (rp,cr) (A0,A1)
  -$0084  -132            WhichLayer (li,x,y) (A0,D0,D1)
  -$008A  -138            UnlockLayerInfo (li) (A0)
  -$0090  -144            NewLayerInfo ()
  -$0096  -150            DisposeLayerInfo (li) (A0)
  -$009C  -156            FattenLayerInfo (li) (A0)
  -$00A2  -162            ThinLayerInfo (li) (A0)
  -$00A8  -168            MoveLayerInfrontOf (layer_to_move,
                          layer_to_be_in_front_of) (A0,A1)

 MATHFFP.LIBRARY
  -$001E  -30             SPFix (float) (D0)
  -$0024  -36             SPFit (integer) (D0)
  -$002A  -42             SPCmp (leftFloat,right,Float) (D1,D0)
  -$0030  -48             SPTst (float) (D1)
  -$0036  -54             SPAbs (float) (D0)
  -$003C  -60             SPNeg (float) (D0)
  -$0042  -66             SPAdd (leftFloat,rightFloat) (D1,D0)
  -$0048  -72             SPSub (leftFloat,rightFloat) (D1,D0)
  -$004E  -78             SPMul (leftFloat,rightFloat) (D1,D0)
  -$0054  -84             SPDiv (leftFloat,rightFloat) (D1,D0)

 MATHIEEEDOUBBAS.LIBRARY
  -$001E  -30             IEEEDPFix (integer,integer) (D0,D1)
  -$0024  -36             IEEEDPFit (integer) (D0)
  -$002A  -42             IEEEDPCamp (integer,integer,integer,integer)
                          (D0,D1,D2,D3)
  -$0030  -48             IEEEDPTst (integer,integer) (D0,D1)
  -$0036  -54             IEEEDPAbs (integer,integer) (D0,D1)
  -$003C  -60             IEEEDPNeg (integer,integer) (D0,D1)
  -$0042  -66             IEEEDPAdd (integer,integer,integer,integer)
                          (D0,D1,D2,D3)
  -$0048  -72             IEEEDPSub (integer,integer,integer,integer)
                          (D0,D1,D2,D3)
  -$004E  -78             IEEEDPMul (integer,integer,integer,integer)
                          (D0,D1,D2,D3)
  -$0054  -84             IEEEDPDiv (integer,integer,integer,integer)
                          (D0,D1,D2,D3)

 MATHTRANS.LIBRARY
  -$001E  -30             SPAtan (float) (D0)
  -$0024  -36             SPSin (float) (D0)
  -$002A  -42             SPCos (float) (D0)
  -$0030  -48             SPTan (float) (D0)
  -$0036  -54             SPSincos (leftFloat,rightFloat) (D1,D0)
  -$003C  -60             SPSinh (float) (D0)
  -$0042  -66             SPCosh (float) (D0)
  -$0048  -72             SPTanh (float) (D0)
  -$004E  -78             SPExp (float) (D0)
  -$0054  -84             SPLog (float) (D0)
  -$005A  -90             SPPow (leftFloat,rightFloat) (D1,D0)
  -$0060  -96             SPSqrt (float) (D0)
  -$0066  -102            SPTieee (float) (D0)
  -$006C  -108            SPFieee (float) (D0)
  -$0072  -114            SPAsin (float) (D0)
  -$0078  -120            SPAcos (float) (D0)
  -$007E  -126            SPLog10 (float) (D0)

 POTGO.LIBRARY
  -$0006  -6              AllocPotBits (bits) (D0)
  -$000C  -12             FreePotBits (bits) (D0)
  -$0012  -18             WritePotgo (word,mask) (D0,D1)

 TIMER.LIBRARY
  -$002A  -42             AddTime (dest,src) (A0,A1)
  -$0030  -48             SubTime (dest,src) (A0,A1)
  -$0036  -54             CmpTime (dest,src) (A0,A1)

 TRANSLATOR.LIBRARY
  -$001E  -30             Translate (inputString,inputLength,
                          outputBuffer,bufferSize) (A0,D0,A1,D1)


 Abbreviations (symbols) used:

          label     A label or address
          reg       Register
          an        Address register n
          dn        Data register n
          source    source operand
          dest      destination operand
          <ea>      address of register
          #n        direct value


 GENERAL INSTRUCTIONS

          BCC   label         Conditional branch, depends on condition.
          BRA   label         Unconditional branch (Similar to JMP).
          BSR   label         Branch to subprogram. Return address is
                              deposited on the stack, RTS causes return to
                              that address.
          CHK   <ea>,dx       Check data register for limits, activate the
                              CHK instruction exception.
          DBCC  reg,label     Check condition, decrement on branch.
          JMP   label         Jump to address (Similar to BRA).
          JSR   label         Jump to a subroutine. Return address is deposited
                              on stack, RTS causes return to that address.
          NOP                 No operation.
          RESET               Reset peripherals (Caution!).
          RTE                 Return from exception.
          RTR                 Return with loading of flags.
          RTS                 Return from subroutine (After BSR or JSR).
          SCC   <ea>          Set a byte to -1 when condition is met.
          STOP                Stop processing (Caution!).
          TRAP  #n            Jump to an exception.
          TRAPV               Check overflow flag, then TRAPV exception.


 ARITHMETIC OPERATIONS WITH WHOLE NUMBERS

          ADD   source,dest   Binary addition.
          ADDA  source,an     Binary addition to an address register.
          ADDI  #n,<ea>       Addition with a constant.
          ADDQ  #n,<ea>       Fast addition of a constant which can be only
                              from 1 to 8.
          ADDX  source,dest   Addition with transfer in X flag.
          CLR   <ea>          Clear an operand.
          CMP   source,dest   Comparison of two operands.
          CMPA  <ea>,an       Comparison with an address register.
          CMPI  #n,<ea>       Comparison with a constant.
          CMPM  source,dest   Comparison of two memory operands.
          DIVS  source,dest   Sign-true division of a 32 bit destination by
                              a 16 bit source operand. The result of the
                              division is stored in the LO word of the
                              destination, the remainder in the HI word.
          DIVU  source,dest   Division without regard to sign, similar to DIVS.
          EXT   dn            Sign-true expansion to twice original size
                              (width) data unit.
          MULS  source,dest   Sign-true multiplication of two words into one
                              word.
          MULU  source,dest   Multiplication without regard to sign, similar
                              to MULS.
          NEG   <ea>          Negation of an operand (twos complement).
          SUB   source,dest   Binary subtraction.
          SUBA  <ea>,an       Binary subtraction from an address register.
          SUBI  #n,<ea>       Subtraction of a constant.
          SUBQ  #n,<ea>       Fast subtraction of a three bit constant.
          SUBX  source,dest   Subtraction with transfer in X flag.
          TST   <ea>          Test operand and set N and Z flag.


 BINARY CODED DECIMAL NUMBERS

          ABCD  source,dest   Addition of two binary coded decimal numbers.
          NBCD  source,dest   Negation of a binary coded decimal number
                              (nine complement).
          SBCD  source,dest   Subtraction of two binary coded decimal numbers.


 LOGICAL OPERATIONS

          AND   source,dest   Logic AND.
          ANDI  #n,<ea>       Logic AND with a constant.
          EOR   source,dest   Exclusive OR.
          EORI  #n,<ea>       Exclusive OR with a constant.
          NOT   <ea>          Inversion of an operand.
          OR    source,dest   Logic OR.
          ORI   #n,<ea>       Logic OR with a constant.
          TAS   <ea>          Check a byte and set bit 7.


 SINGLE BIT MANIPULATION

          BCHG  #n,<ea>       Change bit n(0 is changed to 1 and vice versa).
          BCLR  #n,<ea>       Clear bit n.
          BSET  #n,<ea>       Set bit n.
          BTST  #n,<ea>       Test bit n, result is desplayed in Z flag.


 SHIFT AND ROTATE OPERANDS

          NOTE: n indicates a register, # indicates a direct value which
                specifies the number of shiftings.

          AS    n,<ea>        Arithmetic shift to the left (*2^n)
          ASR   n,<ea>        Arithmetic shift to the right (/2^n)
          LSL   n,<ea>        Logic shift to the left.
          LSR   n,<ea>        Logic shift to the right.
          ROL   n,<ea>        Rotation left.
          ROR   n,<ea>        Rotation right.
          ROXL  n,<ea>        Rotation left with transfer in X flag.
          ROXR  n,<ea>        Rotation right with transfer in X flag.


 MOVE DATA INSTRUCTIONS

          EXG   rn,rn         Exchange two register contents (don't confuse
                              with swap!).
          LEA   <ea>,an       Load an effective address in address register an.
          LINK  an,#n         Build stack range.
          MOVE  source,dest   Carry value over from source to destination.
          MOVE  SR,<ea>       Transfer the status register contents.
          MOVE  <ea>,SR       Transfer the status register contents.
          MOVE  USP,<ea>      Transfer the user stack pointer.
          MOVE  <ea>,USP      Transfer the user stack pointer.
          MOVEA <ea>,an       Transfer a value to the address register an.
          MOVEM regs,<ea>     Transfer several registers at once.
          MOVEM <ea>,regs     Transfer several registers at once.
          MOVEP source,dest   Transfer data to peripherals.
          MOVEQ #n,dn         Quickly transfer an eight bit constant to the
                              data register dn.
          PEA   <ea>          Deposit an address on the stack.
          SWAP  dn            Swap the halves of the register (the upper 16 bit
                              with the lower).
          UNLK  an            Unlink the stack.


                          --=End of Book=--          
                          
LSD greetings go to; DEE JAY (well done and thanx!), RAZOR BLADE (Mr Abacus!), 
RYGAR, SCOOTER, and all docs fans everywhere!  
                         
