CHAPTER 16


MENUS

This chapter describes the operating system menu-handling facility, and the how the top level menu may be customised. Using this, menus can be displayed, and menu items selected, in the same way as in the top level control routines of the operating system.


16.1 SYSTEM SERVICES


16.1.1 MN$DISP

VECTOR NUMBER: 080
INPUT PARAMETERS:
     D register - Terminating bit-mask.
     X register - Address of menu-list.
OUTPUT VALUES:
     A register - Flag to indicate the type of contents in the X register.
     X register - Depends on value of A register.
     B register - Terminating key press.
     UTW_S0 - Number of the menu item selected (0 for first item).

DESCRIPTION

Displays a menu according to the specified menu-list at X, allowing the user to scroll through the menu using the arrow keys or by pressing the first letter of the item to be selected.

The menu-list consists of item names (with leading byte-count), each followed by the address of an associated subroutine, or by 0. The list is terminated by a name of length 0. The maximum name length is 16. The items are displayed (and numbered) in the same order as in the menu-list. The first item is displayed at the top left-hand corner (HOME position) of the LCD display. The display is filled from left to right until an item is too long to fit, in which case a new line is started. The error ER_RT_ME is returned when

  1. the menu-list is so large that the total number of characters displayed (including the spaces inserted for padding) exceeds 254, or
  2. the menu has no items (i.e. 0 in the first byte of the menu-list).

In the terminating mask, the n'th bit set corresponds to allowing termination on pressing key value n+1. For instance, bit 0 set corresponds to allowing termination on pressing the ON/CLEAR key, which has value 1. See section 7.1 for values of control keys).

MN$DISP exits when the user either

  1. presses any of the keys specified by the bit-mask, or
  2. selects by pressing its first letter, an item with a unique first letter, but only when the EXE key is also specified in the terminating bit-mask. (In this case, the terminating key press returned in B will be EXE, since MN$DISP forces an exit _as if_ EXE has been pressed too).

When the routine terminates, it returns in X the address of the subroutine corresponding to the item selected, unless this address is is 0. If it is 0 then the routine returns in X the address of the item's name in the menu-list.

The B register is returned with the terminating key press (or with EXE when terminating on pressing an item's initial letter).

The A register is returned with 0 if the item had an associated subroutine address (non-zero), and otherwise A equals 1. UTW_S0 is returned with the number of the menu item, where 0 specifies the first item.

EXAMPLE:

Displays and gets the selection from a menu that has three items. Calls the subroutine associated with the item if specified in the menu-list, and otherwise runs the language procedure which has the name of the selected item.

MENU_LIST:
         .ASCIC  "FIRST"                 ; First item (item number 0)
         .WORD   FIRST_SUBROUTINE        ; Address of subroutine to be
                                         ;   called on selecting FIRST
         .ASCIC  "SECOND"                ; Second item (item number 1)
         .WORD   0                       ; No associated subroutine
         .ASCIC  "THIRD"                 ; Third item (item number 2
         .WORD   THIRD_SUBROUTINE        ; Address of subroutine to be
                                         ;   called on selecting THIRD
         .BYTE   0                       ; Terminate the list
DO_MENU:
         LDX     MENU_LIST               ; Point to the menu-list
         LDD     #$1002                  ; Terminate on EXE or MODE i.e. 2
                                         ;    or 13, so set bits 1 and 12
         OS      MN$DISP                 ; Call the service
         CMP     B,#K_EXE                ; EXE pressed?
         BNE     MODE                    ; No, so MODE was pressed
         TST     A                       ; Was there a subroutine address?
         BNE     2$
         JMP     0,X                     ; Yes, so run the subroutine
 2$:     CLR     B
         OS      RM$RUNP                 ; No, so run language procedure
                                         ;   (B=0 for not in the calculator)
         BCS     ERROR                   ; Handle error
         RTS 
MODE:                                    ; Here if MODE was pressed

ERRORS:

ER_RT_ME - menu error

BUGS

If the D register is passed as 0 then the routine will never exit as there will be no valid terminating character. Also note that this routine puts the keyboard state into alpha shift.


16.2 TOP LEVEL MENU

The top level menu is held in RAM in the second allocator cell, whose address is at $2002. See chapter 6 for information about the storage allocator. The structure of menus is described in the previous section. Either OPL procedures or machine code programs may be called from the top-level menu.

The menu can be manipulated by the system services TL$ADDI, TL$DELI.


16.2.1 TL$ADDI

VECTOR NUMBER: 101
INPUT PARAMETERS:
     B register - position in menu-list
OUTPUT VALUES: None.

DESCRIPTION

Inserts a given menu item into the top-level menu at position B. B = 0 means insert at the start, B = 1 means after the first item, B = $FF means insert before the "OFF".

The menu item to be inserted is placed at address RTBBL. It must consist of :

The length of the item name may not be zero. The first character of the item name must be a letter, the following characters may be alphanumeric, or "$" or "%", otherwise error BAD PROCEDURE NAME is returned.

Note that the item is not necessarily a legal OPL procedure name. No error will be returned for items names such as "A$$$", "A " or names longer than eight characters.

The item name is followed by an execution address. When the menu item is selected by the user, the operating system will treat the menu item name as an OPL procedure if the execution address is zero. The operating system will otherwise call a machine code routine at the execution address.

TL$ADDI is called after the "INSERT ITEM" prompt when the MODE key is pressed at the top level. In this case the execution address is zero.

Note that TL$ADDI does not recognise the standard menu items FIND, SAVE etc. as special. This allows the user to replace the standard system menu items with different routines.

EXAMPLES

;       CODE USED IN THE RS232 TO INSERT "COMMS" INTO TOP LEVEL MENU BEFORE "OFF"
         LDX     #COMMS_STRING   ; COPY MENU ITEM FROM COMMS_STRING
         LDD     #END_COMMS-COMMS_STRING
         STD     UTW_S0:         ; NUMBER OF BYTES TO COPY
         LDD     #RTB_BL         ; INTO WORKSPACE FOR TL$ADDI
         OS      UT$CPYB
         LDA     B,#^XFF         ; B = WHERE TO INSERT THE ITEM
         OS      TL$ADDI         ; INSERT IT
         RTS
COMMS_STRING:
         .BYTE   COMMS1 - COMMS_STRING       ; LENGTH OF "COMMS"
         .ASCII  "COMMS"         ; NAME OF MENU ITEM TO BE INSERTED 
COMMS1: .WORD   COMMS_START      ; START ADDRESS OF COMMS CODE 
END_COMMS:

ERRORS:

    ER_LG_BN    197     BAD PROC NAME   - see above
    ER_RT_ME    202     MENU TOO BIG
    ER_AL_NR    254     OUT OF MEMORY


16.2.2 TL$DELI

VECTOR NUMBER: 103
INPUT PARAMETERS:
     X register - address of item name to be deleted
OUTPUT VALUES: None.

DESCRIPTION

Deletes the item named at X from the top level menu. The item at X is a leading count byte string.

EXAMPLE

    ;   CODE USED IN THE RS232 TO DELETE "COMMS" FROM TOP LEVEL MENU
         LDX     #COMMS_STRING
         OS      TL$DELI         RTS
    COMMS_STRING:
         .BYTE   5               ; LENGTH OF "COMMS"
         .ASCII  "COMMS"         ; NAME OF MENU ITEM TO BE REMOVED

ERRORS: None