Menu, Topic, Help (MTH)
Each application can have a set of 'topics' associated with it. These topics appear in the topic window on the left hand edge of the screen, below the application name. Normally all the topics are in grey but when the menu key is pressed a topic name is highlighted and a menu display is brought up. The menu consists of up to three columns of commands, which may be selected with a highlight bar or by using a special keyboard sequence also shown on the menu. Each topic and each command may have a page of help text associated with it and in addition the application itself may have a page of help text, perhaps for a general description of its function. An extra information topic, not displayed in the topic window, may be added to provide access to a series of help pages which are not directly associated with keyboard commands. This is useful to explain general features of the application or tips of command usage.Â
Limitations and conventions
There are some limitations and conventions regarding menu topics and help; the limitations are:
- Diamond sequences should consist of no more than 5 characters, although these may be special characters like arrow keys and Delete.
- The first possible match will be selected, so if a diamond sequence 'AB' exists, there is no point having 'ABC' as it cannot be selected.
- No command code should be zero, as two zeroes from 'OS_In' are used to represent NUL. Note also that the <SPACE>, <TAB>, <ENTER> and the arrow keys all return command codes and you must make sure you do not clash with these. See "Input and the Keyboard Decoder" for details of these codes.
- There should be no more than 7 topics per application and no more than 24 commands per topic. Each command name should consist of no more than 25 characters.
- If any commands in a topic have help, then it is strongly recommended that all the topics have help, even if this is just a blank page (set the help pointer to point to a NUL) and the topic itself must have help.Â
The conventions, we recommend you subscribe to, are:
- Make the first letter of a diamond sequence the first letter of the topic name (eg. PipeDream has BNEW in the Blocks topic).
- If topic names coincide with the internal ones, then the order should be the same, eg. 'CURSOR' before 'FILES'.
- Commands associated with the arrow keys should be in the order: Right, Left, Up and Down.Â
Â
Topic information
The 'pointer to topics' is of the form of a 2 byte offset in a bank, followed by a bank number. The pointer should point to a series of topic definitions arranged like this:
           1 byte       0          Start marker
           x bytes                  <first definition>
           x bytes                  <second definition>
           ...
           ...
           x bytes                  <last definition>
           1 byte       0          End marker
Where each definition has the following form:
a          1 byte       b-a        length byte
           n bytes      'xxxxx'    topic name
           1 byte       0          optional null-terminator (see below)
           2 bytes      x x        Optional pointer to topic help page, if
                                     any. This is a 2-byte pointer relative to
                                     the start of the help text. NOTE: it is
                                     stored as high byte, low byte sequence
                                     (reverse of the conventional order).
           1 byte       x          topic attribute byte
           1 byte       b-a        length byte
b
The topic attribute byte:
bit 0Â Â Â Â Â Â set for an 'An' topic eg. 'An Edit topic' - default is 'A'
bit 1Â Â Â Â Â Â set for an information topic - see below
bits 2-3Â Â Â should be 0
bit 4Â Â Â Â Â Â set if topic entry has a pointer to a help page
bits 5-7Â Â Â should be 0
The topic name terminator can simply be a null, but in fact any control character (ie. $00-$1F) will serve perfectly well. Therefore it is possible to use the attribute byte, or the high byte of the help pointer (hence the high byte, low byte ordering - although this won't apply if the help text length is more than 8K - the high byte becoming $80) to terminate the name. The system looks at the attribute and help pointers by counting back from the end of the topic entry, so there is no confusion between a term inator and an attribute byte or help pointer.
NOTE: Due to a bug in OZ it is necessary when creating information topics (bit 1), that the definitions must be placed before any command topics otherwise they are not recognized by the system.Â
Â
Command Information
The 'pointer to commands' is of the form of a 2 byte offset in a bank, followed by a bank number. The pointer should point to a series of command definitions arranged like this:
           1 byte       0          Start marker
           x bytes      def(1,1)   first command of first topic
           x bytes      def(1,2)   second command of first topic
           ...
           x bytes      def(1,x)   last command of first topic
           1 byte       1          End of this topic
           x bytes      def(2,1)   first command of second topic
           ...
           x bytes      def(2,x)   last command of second topic
           1 byte       1          End of this topic
           x bytes      def(x,1)   first command of last topic
           x bytes      def(x,y)   last command of last topic
           1 byte       0          End of all topics
Each of these definitions should have the following form:
a          1 byte       b-a        length byte
           1 byte       x          command code (see below)
           x bytes      'xxx',0    null-terminated keyboard sequence for
                                     command.
           x bytes      'xxxxx'    Command name. The total length of the name
                                     and keyboard sequence must be 25 characters
                                     or less. Any control characters which you
                                     need to use must be brought in via tokens.
           1 byte       0          optional null-terminator (see below)
           2 bytes      x x        Optional pointer to command help page, if
                                     any. This is a 2-byte pointer relative to
                                     the start of the help text. NOTE: it is
                                     stored as high byte, low byte sequence
                                     (reverse of the conventional order).
           1 byte       x          command attribute byte
           1 byte       b-a        length byte
b
The command attribute byte:
bit 0Â Â Â Â Â Â set to make this entry the first in a new column. Note: the last
           entry in a column has no special attribute. Set this bit even
           though the previous column is used up, otherwise the system gets
           confused in displaying the entries.
bit 1Â Â Â Â Â Â should be set to 0
bit 2Â Â Â Â Â Â set to make a hidden entry. The command name and key sequence will
           not appear on the menu display. This is useful for commands which
           need to key sequences. eg. in PipeDream <>TAB is a hidden entry
           which does the same thing as <>CFC, by having the same command
           code. Hidden entries may have Help text, but this text will never
           be displayed. Note: A hidden entry must never be the last in a
           topic. If it is the Help system will not be fully traversable and
           the system will crash if the user moves through help in a certain
           way.
bit 3Â Â Â Â Â Â set to make safe. Setting this bit forces to use the user to use
           the keyboard sequence rather than selecting the command with the
           highlight bar in the menu display. This is used by the system for
           the Index commands <>KILL and <>PURGE. An attempt to access these
           commands through the highlight bar results in a double bleep. These
           entries should have their command name in tiny text, by convention.
           This has to be done using a token, since control characters will
           terminate a command name.
bit 4Â Â Â Â Â Â set if command entry has a pointer to a help page.
bit 5-7Â Â Â Â should be set to 0
NOTE: The same trick of treating the attribute byte, or high byte of the help pointer as a terminator, can be used in menu entries. The command name terminator simply needs to be in the range ($00 - $1F).
The format of the keyboard sequence is as follows:
For a conventional diamond sequence, simply use the upper case letters of the sequence, eg. for the PipeDream New command the entry would be the following bytes "BNEW" & 0 . For commands using other keys the keyboard decoder codes are used. For example <SHIFT><UP><ARROW> is represented by a key sequence consisting of one byte. IN_SUP ($FB) and the terminator, $00. The system automatically generates the graphic sequence from this code. The menu exceptions, which correspond to the screen driver codes, are:
           Key          Symbol     Code
           <SPACE>      MU_SPC     $E0
           <ENTER>      MU_ENT     $E1
           <TAB>        MU_TAB     $E2
           <DEL>        MU_DEL     $E3
When an application reads the keyboard then valid keyboard sequences are intercepted so instead of returning the raw characters, the routine will return a zero, indicating a command - note this means the NUL can never be read in as a normal character. The next keyboard read will then return the relevant command code as specified in the above definition. One way of dealing with this behaviour is for the user to set up a 'read character' routine which will return normal characters without change, but intercept and obey command sequences. The following code fragment indicates a possible arrangement, although you will need to have read "Error handling and related issues" and "Input and the keyboard decoder" to follow it properly.
.rdch      call_oz(OS_In)           ; perform OS_In
           jr  nc, rdch2           ; if no error, continue
           cp  RC_SUSP             ; check RC_SUSP
           jr  z, rdch             ; and ignore if it occurs
           SCF
           RET                      ; return with system error enabled
.rdch2     or  a                   ; reflect on input
           ret nz                  ; return if character is not NUL
           call_oz(OS_In)           ; read command code
           or  a                   ; set flags
           ret z                   ; return if a NUL has been read
           <deal with command code in A>
Help Information
The 'pointer to commands' is of the form of a 2 byte offset in a bank, followed by a bank number. The pointer should point to a series of help page definitions arranged like this:
           x bytes      help page for the application (or 0 for a blank page)
           x bytes      help entry (see below)
           ...
           ...
           x bytes      last help entry
Each help entry will produce one page of help text. It consists of a series of lines, where DEL ($7F) is used for newline, terminated by a NUL ($00). The DEL character is used for newline to facilitate embedding screen driver codes into the help text. For example you can use special keyboard icons, arrow symbols or box characters, eg. for the 'ENTER' icon use the sequence 1 & SD_ENT. The help page is displayed with centred justfification switched on, but you could include a command to switch off centering in your help strings. This should only be done where necessary, to avoid disrupting the overall style of the help pages. The pointer to the help text, which is an offset from the base of the help text, defined in the application DOR, in topic and command entries, should point to the first character of the first line. A help entry might look like this:
.helppage  defm "This is a simple help page" & $7F
           defm "and this is the second line" & 0
Token information
The 'pointer to token base' is of the form of a 2 byte offset in a bank, followed by a bank number. The token table format is shown below.
base       1 byte                   Recursive token boundary (1 - 127)
           1 byte                   Number of tokens (1 - 127)
           2 bytes      first-base pointer to first token
           2 bytes      second-base pointer to second token
           ...
           ...
           2 bytes      last-base  pointer to last token
           2 bytes      end-base   pointer to byte after nth token
.first     x bytes      defm "xxx" first string (no terminators)
.second    x bytes      defm "yyy" second string
           ...
.last      x bytes      defm "zzz" last string
.end
NOTE: the token table must not be allowed to cross a bank boundary (16K).
Tokens may be embedded in the help text or within the text for topic and command names. The first token has a code of $80 and subsequent tokens count up from here. Recursive tokens may contain tokens in their text. Tokens above the boundary level set by the 'first recursive token' may contain tokens themselves, providing those tokens are below the boundary. The example below is in assembly format to improve clarity:
.tok_base  defb $04                             ; recursive token boundary
           defb $05                             ; number of tokens
           defw tok0 - tok_base
           defw tok1 - tok_base
           defw tok2 - tok_base
           defw tok3 - tok_base
           defw tok4 - tok_base
           defw end - tok_base
.tok0Â Â Â Â Â Â defm "file"
.tok1Â Â Â Â Â Â defm " the "
.tok2Â Â Â Â Â Â defm "EPROM"
.tok3Â Â Â Â Â Â defb $01, 'T'Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ; Tiny text token
.tok4Â Â Â Â Â Â defm ' ', $80, "s "
.endÂ
Â
Information topics
The information topic is selected by pressing <HELP> from within the application. If the topic is present then a menu of commands will be brought up. In an application with no other topics, pressing <MENU> will bring up the information topic name in the topic window. The command entries for an information topic topic differ from ordinary commands in that there is no keyboard sequence associated with them. The command entries should look like this:
a          1 byte       b-a        length byte
           1 byte       0          NULL command code
           1 byte       0          NULL keyboard sequence
           x bytes      'xxxxx'    Command name. The total length of the name
                                     must be 25 characters
           1 byte       0          optional null-terminator
           2 bytes      x x        pointer to help page
           1 byte       x          command attribute byte
           1 byte       b-a        length byte
b
The attribute byte should always be $10 (help page) or $11 (help page and first entry in a new column).Â