home *** CD-ROM | disk | FTP | other *** search
- *************************************************************************
- * >E-Command Documents how to add commands to Zap *
- *************************************************************************
-
- As mentioned in the ReadMe file, commands are added to Zap by registering a
- table of commands when the module providing the extra commands initialises.
- You should use the call Zap_AddCommands to register the table. The table has
- the format below. All offsets are from your module start unless otherwise
- indicated.
-
- #0 Offset of table from start of module (so Zap can convert the
- offsets below into addresses).
- #4 Offset from module start of 'Zap service call code' or 0
- if none. Zap calls this entry point to tell you about
- various things - see the section below.
- #8 List of commands, terminated by a zero word. Each element
- of the list has the format:
-
- <command name>+<0 byte terminator>+
- <ZERO bytes padding until word aligned>+
- <word giving command offset from module start>
-
- The command name must be in UPPER CASE in this table. In general, command
- names are not case sensitive, but they are converted to upper case in order
- to search for them in the command tables. The characters padding to the next
- word alignment MUST be ZEROs as the table is searched through in words not
- in bytes.
-
- When a command is found in the table, its address is calculated, and
- henceforth the command is referred to by its address. This unfortunately
- means that I cannot pass the command your module workspace when the command
- is called as I do not know which module the command lies in. This is not
- usually a problem however as you may claim workspace from Zap's heap. If this
- is not sufficient, then you will just have to store the address of your
- workspace in the module itself and read it when you are called (until I work
- out a better method).
-
- The address of the command is of course the address called when the command
- is executed. However, at offset -4, the word before the first instruction of
- the command, some flags are stored. These flags determine what type of
- parameter the command takes and how the command interacts with the
- minibuffer and menus. This word must be filled in. It's meaning is summarised
- below. Greater detail is given further down the file.
-
- b0 Set if the command doesn't need R10 on entry (eg called from
- b1 Set if the command doesn't need R8 on entry a menu).
- b2 Set if the command doesn't need R9 on entry
- b3-b5 Argument type for the command:
- 0 = Command takes no parameters
- 1 = Command takes a list of bytes as parameter
- 2 = Command takes a list of words as parameter
- 3 = Command takes a string as parameter
- 4 = Command takes a block of data as parameter
- 5-7 reserved
- b6 Set if you wished to be called before minibuffer opened
- b7 Set if you wish to be called after every minibuffer update
- b8 Set if you wish to be called before a key is inserted into
- the minibuffer (and possibly alter it).
- b9 Set if you want TAB to complete file names in the minibuffer
- b10 Set if you may want to kill the minibuffer when it starts up.
- b11 Set if you may want minibuffer to remain open when command finished.
- b12 Set if Universal arg should multiply R1 by the number of times to do.
- b13 Set if command should be called repeatedly with R1 smaller.
- b14 Set if the command should not be executed when loading a file.
- b15 Set if the command is 'tickable' when on a menu entry.
- b16 Set if the command can create a submenu or leaf window.
- b17 Set if the command can provide a default string for a menu entry.
- b18 Set if the command wishes to provide the menu entry text.
- b19 Set if the command wishes to specify the submenu.
- b20 Set if the command may wish to remove the menu entry.
- b21-b31 Reserved - set to 0
-
- The entry/exit conditions of your command depend on your flags word as I will
- detail below. When the command is called the registers have the meaning:
-
- R0 = input data for the command (dependent on R2 & command type - see below)
- R1 = length of input data (dependent on R2 & command type - see below)
- R2 = action code (details below)
-
- R8 = window of the input caret (see E-Windows) (unless flags b1 set)
- R9 = file block associated with R8 (see E-File) (unless flags b2 set)
- R10 = cursor block pointer of input cursor (see E-Cursors)
- (unless flags b3 set) (This is car_cursor if the cursors are combined
- and car_input if they are split - see E-Vars).
- R11 = undefined
- R12 = Zap's workspace
- R13 = small FD stack
-
- ALL calls to your command have these registers set up. The descriptions of R0
- and R1 given above are for action code R2=0 (execute the command). In general
- their meaning will be dependent on R2 and are undefined otherwise. Note that
- you are only called with the action codes you request via your flags word so
- do not need to test for all possible action codes.
-
- On exit from a command you may corrupt the registers R0-R11 and the flags.
- You should return V flag set and R0=error block on error. Some of the calls
- with R2<>0 require you to return a result in R0. To detail the actual meaning
- of R0-R2 I have partitioned into cases below. Registers not mentioned are
- undefined.
-
- If you want to call a command yourself, then please use the call
- Zap_ProcessCommand or Zap_CommandString. All calls from Zap are made by this
- method. See the file 'Commands' for the syntax used when typing a command
- into the keys file, or sending it to Zap_CommandString.
-
- NB Only command calls with R2=0 or R2=1 are learnt. All other calls are
- regarded as 'setup' calls and are not learnt.
-
- ************************
- * Details of flag bits *
- ************************
-
- Bit 0
- -----
-
- If this bit is set then R10 is undefined on entry. If it is clear then the
- current position of the input cursor will be read if R10 is not specified (ie
- is 0) when Zap_ProcessCommand is called. Note that reading the current
- input cursor position may change R8 and R9 as well.
-
- This is useful when the command is called from a menu. The menu may not be on
- the window with the input focus. If this bit is set then the command can act
- on the menu the window is on, where as if it is clear then it will always act
- on the window with the input focus. Thus it should be set for any command
- which only affects the window state and doesn't need to know the cursor
- position.
-
- Bit 1
- -----
-
- If this bit is set then R8 either points to a window or is 0 on entry. If 0
- then the command is being called from the options menu to change the default
- state. If the bit is clear and Zap_ProcessCommand is called with R8=0 then an
- error is given.
-
- Thus this bit should be set for commands which don't need to know where the
- cursor is and can change the default options as well as the current window
- state. If this bit is set then you should also set Bit 0.
-
- Bit 2
- -----
-
- As for Bit 1 except that the file pointer R9 is checked instead of R8. If the
- command is called from the options menu then both R8 and R9 will be 0.
-
- Bits 3-5
- --------
-
- These determine what type of data the command takes. When the command is
- executed it is called with R2=0. In general the meaning of R2>0 is documented
- under the Bit with value R2. Note that Bits 12 and 13 are used in deciding
- which value is passed in R1. When the command is called with R2=0 additional
- information is passed in R3:
-
- R3 = b0 Set => This command was executed as the last command as well.
- (eg to spot cumulative ctrl K's/Yanks).
- b1-b27 => Reserved
- b28-b31=> Top bits of R2 when command called via Zap_ProcessCommand.
-
- Data type None (0) is called with:
-
- R0=undefined
- R1=number of times the key has been pressed (depends on flags bits):
- Suppose the key has been buffered a total of m times. Suppose also that
- Universal argument (^U) is active and that the user has requested a
- repetition of n times. (n=1 if universal argument not active).
- Ie, Zap_ProcessCommand has been called with R1=m. Then:
- b12=0 & b13=0 => Command is called n times with R1=m
- b12=1 & b13=0 => Command is called once with R1=m*n
- b12=0 & b13=1 => Command is called m*n times with R1=1
- b12=1 & b13=1 => Command is called m times with R1=n
- ie b12=1 => R1 is multiplied by n (the universal argument)
- b13=1 => Called an extra m times with R1 divided by m.
- R2=0 to execute the command.
-
- Data type Byte list (1):
-
- If the command takes a byte parameter, then when the keyboard input is
- buffered, the bytes are buffered in a list as well. Hence the sequence
- of keypresses: CHAR 65,CHAR 66,CHAR 67 will cause the command CHAR to be
- called once with data list 65,66,67 (if b13=0).
-
- R0=pointer to a list of the bytes
- R1=number of bytes in the list (depends on flag bits):
- If m,n are as above (ie Zap_ProcessCommand has been called with R1=m,
- R0 pointing to a list of m bytes, and universal command repeat=n) then:
- b12=0 & b13=0 => Command is called n times with R1=m and the list of
- bytes pointed to by R0 is m long.
- b12=1 & b13=0 => Command is called once with R1=m*n and the list
- of bytes pointed to by R0 is m*n long. Ie, the
- list passed to Zap_ProcessCommand has been
- duplicated n times.
- b12=0 & b13=1 => Command is called m*n times with R1=1 and
- R0 pointing to the single byte argument. (R0
- incremented between command calls and wraps round).
- b12=1 & b13=1 => Command is called m times with R1=n and R0 pointing
- to the single byte argument. (R0 is incremented by
- 1 byte on each command call so it covers the list
- of m bytes passed to Zap_ProcessCommand).
- R2=0 to execute the command.
-
- Data type Word list (2):
-
- The details are the same as for Byte list typed data except that R0 points
- to a list of words and R1 is the number of words (not bytes) in the list.
-
- Data type String (3) is called with:
-
- R0=pointer to the string (zero terminated)
- R1=number of times key pressed (as for data type None above)
- R2=0 if the string was specified (eg INSERT "Wibble")
- 1 if the string wasn't specified (eg INSERT) but has been typed into
- the minibuffer (R0 points to the minibuffer contents in this case)
- and then RETURN has been pressed.
-
- You can control the minibuffer, and the way the string is entered by using
- bits 6-11 as documented below. Please set bit 6 and add a prompt where
- possible. Your command should end up taking the same action regardless of
- whether R2=0,1 for when learnt sequences are played back you are always
- called with R2=0.
-
- Data type Block (4) is called with:
-
- R0=pointer to a data block (of command dependant format)
- R1=number of times key pressed (as for data type None above)
- R2=0 to execute the command.
-
- This is used by the command MULTICOMMAND which is used internally within
- Zap to execute a compiled list of other commands. You cannot use this type
- of command in the Keys file as there is no way to specify a parameter.
-
- Bit 6
- -----
-
- This bit is only used if the command takes a string parameter and it has not
- been supplied. The minibuffer is opened in this case and, if this bit is set,
- you are called to supply a prompt and add a default string after the prompt
- if you like. You are called with R2=6 (R0,R1 undefined). See also bit 10.
-
- The minibuffer is cleared before you are called and opened on screen AFTER
- you return. Use Zap_MiniPrompt to add the prompt and Zap_MiniWrite to alter
- the contents of the rest of the minibuffer.
-
- Bit 7
- -----
-
- This bit is only used if the command takes a string parameter and the
- minibuffer has been opened. If this bit is set then you are called AFTER each
- key has been inserted into the minibuffer so you can examine its contents.
- You are called with:
-
- R0=pointer to minibuffer contents (after the prompt)
- R1=undefined
- R2=7
-
- The minibuffer is updated on screen after you return.
-
- Bit 8
- -----
-
- This bit is only used if the command takes a string parameter and the
- minibuffer has been opened. If this bit is set then you are called BEFORE
- each key has been inserted into the minibuffer. You are called with:
-
- R0=pointer to minibuffer contents (after the prompt)
- R1=undefined
- R2=&8000+Zaps internal key number of the key about to be inserted into
- the minibuffer.
-
- and you should return:
-
- R0=-1 => leave the minibuffer unaltered - key not inserted (but you will
- be called again if b7 is set).
- 0-&1FF => insert that key (Zap internal key number). Hence you will
- usually exit via SUB R0,R2,#&8000. Returning &1B (Escape) will cause
- the minibuffer to be closed.
- &8000+key number => The minibuffer is quitted as if return had been
- pressed (ie you are called with R2=1 etc) and the the indicated key
- is acted on as if typed in the editing window.
-
- You should use this call to trap insertions of TAB and make it act as a
- completion key. Filename completion can be done automatically - see b9.
-
- Bit 9
- -----
-
- If set then the TAB key automatically acts a 'filename completion' in the
- minibuffer.
-
- Bit 10
- ------
-
- This bit is only used if the command takes a string parameter and the
- minibuffer has been opened and bit 6 is also set. When you are called with
- R2=6 then if bit 10 is also set you should return with:
-
- R0=0 => continue as usual - ie open the minibuffer.
- 1 => total abort - you are opening your own window or something.
- >1 => abort the minibuffer and execute the command as normal with R2=0
- and with parameter the string pointed to by this R0.
-
- NB Do not execute the command on this call - it will not be leant. This is
- why you should pass the argument back in R0.
-
- Bit 11
- ------
-
- This bit is only used if the command takes a string parameter and the
- minibuffer has been opened. When the user presses return the minibuffer is
- usually closed after you have been called with R2=1 to execute the command.
- If this bit is set then you can return a value in R0 (from being called with
- R2=1) to stop this:
-
- R0=0 => close the minibuffer as usual.
- 1 => leave the minibuffer open.
-
- Bit 12-13
- ---------
-
- These control the value of R1 when your command is called with R2=0. See Bits
- 3-5 for more details.
-
- Bit 14
- ------
-
- If set then the command is regarded as 'unsafe'. Ie, it could possibly be
- used in a Trojan an should not be executed automatically on the loading of a
- text file by specifying it in the first few lines of the file. The OSCLI
- command is a good example of this.
-
- Bit 15
- ------
-
- This bit is only used if the command is used on a menu entry. If set then
- you are asked whether the menu item should be ticked or shaded. You are
- called when the menu entry is opened with:
-
- R0=command data (pointer to byte/word/string)
- R2=15
- R10 need not be valid even if b1 is clear (R10=0 if not valid)
-
- and you should return
-
- R0 = b0 set => menu item should be ticked
- b1 set => menu item should be shaded
- b2+ reserved - set to 0
-
- Bit 16
- ------
-
- This bit is only used if the command is used on a menu entry. If set then it
- indicates that the command can be used as a submenu pointer. The submenu
- warning bit is set and when the user tries to open the submenu you are called
- with R2=16 and should return:
-
- R0 = window handle of a leaf window to open off the menu
- OR pointer to a wimp menu structure to open with Zap data at
- negative offsets (see E-Menu).
-
- For example the command 'Save' opens the 'Save dialogue box' and returns the
- window handle of it. This is compatible with the normal action of the Same
- command when executed which is to open the box.
-
- If bit 16 is clear and your command is used as a submenu then instead a
- writable icon is produced and the contents sent to the command when the user
- clicks on it. See bit 17.
-
- Bit 17
- ------
-
- This bit is only used when the command is used as a submenu pointer in the
- 'menus' file and bit 16 is clear. In this case a writable menu icon is
- provided for the user to type in the command argument. It this bit is set
- then you are asked to provided (1) a title for the menu containing the
- writable icon (2) a default string to place in the icon when the menu is
- created (usually a default value) (3) the size of the buffer in the writable
- icon. You are called with R2=17 and
-
- R0=0 => Return R0 as a pointer to the title string to use for the menu
- (a maximum of 12 characters long and zero terminated).
- R0=1 => If your command is of type 3 (string) then:
- Return R0 as a pointer to the string to insert in the buffer
- OR 0 to clear the buffer
- OR -1 to leave the buffer as it currently is.
- OR bit 31 set and +ve integer to insert in b0-b30
- If your command is of type 1/2 (byte/word) then:
- Return R0 as a pointer to the number to insert in the buffer
- OR 0 to clear the buffer
- OR -1 to leave the buffer unaltered.
- Set b31 of R0 if you want the number inserted in hex.
- R0=2 => Return R0 as the size in characters the buffer should be.
- R0>2 => Ignore - I may add further reason codes in future.
-
- If bit 17 is clear then this call is handled for you and the default values
- used are:
-
- (1) The title string is set to the name of the command as appearing in the
- menus file.
- (2) Buffer is left unchanged when the menu is updated.
- (3) Buffer is made 16 characters wide if command takes a string argument
- or 8 if it takes a numerical argument.
-
- Bit 18
- ------
-
- This is only used when the command is used on a menu. If set then you are
- called to provide replacement text for the menu entry, overwriting what is
- already in the buffer. The number of characters in the menu entry text
- defines the size of the buffer reserved for the string. This is called
- whenever the menu is opened so the menu can change dynamically. You are
- called with:
-
- R0=pointer to command data (byte/word/string)
- R2=18
-
- and should return
-
- R0=pointer to text for the menu item (which may be clipped by Zap if it
- doesn't fit in the buffer) / 0 if none (menu left as it is).
-
- Bit 19
- ------
-
- This is only used when the command is used on a menu. If set then you are
- called to provide a submenu to appear off this command. This is called every
- time the menu is opened, but not called if an alternative submenu is
- provided in the Menus file. You are called with:
-
- R0=pointer to command data (byte/word/string)
- R2=19
-
- and should return
-
- R0=pointer to submenu (in Zap-Wimp format) or 0 for none.
-
- Bit 20
- ------
-
- This is only used when the command is used on a menu. If set then you are
- asked whether the menu item should be omitted from the menu (for example the
- mode it accesses doesn't exist). This is called whenever the menu is opened
- so the menu entry can appear and disappear dynamically. It doubles memory
- used by the menu so don't use if unnecessary. You are called with:
-
- R0=pointer to command data (byte/word/string)
- R2=20
-
- and should return
-
- R0=b0 set to remove the menu item
- b1-31 reserved (set to 0)
-
- Bit 21-31
- ---------
-
- Reserved - must be 0.
-
- ************
- * EXAMPLE *
- ************
-
- The code below implements a simple command which asks you to enter a number
- into the minibuffer and then switches to that display mode. FNcall is a macro
- which calls the named Zap entry point (see E-Zapcalls for its definition).
-
- EQUD (3<<3)+(1<<6) \ string argument + ask for prompt
- .command_start
- STMFD R13!,{R14}
- TEQ R2,#6 \ is the minibuffer about to open
- BEQ add_prompt
- FNcall(Zap_MiniEval) \ find the number typed
- LDMVSFD R13!,{PC} \ error
- LDMCSFD R13!,{PC} \ wasn't a valid number
- FNcall(Zap_NewMode) \ change mode
- LDMFD R13!,{PC} \ finished
- .add_prompt
- ADR R0,prompt_string
- FNcall(Zap_MiniPrompt) \ insert the prompt string
- LDMFD R13!,{PC}
- .prompt_string
- EQUS "New mode: "+CHR$0
- ALIGN
-
- It is the offset of command_start that you must place in your command table,
- not the offset of the EQUD flags word before it. Note that the command
- performs the same action regardless of whether R2=0 or R2=1.
-
- *********************
- * Zap service calls *
- *********************
-
- If the second word in your command table is non zero then it gives the
- module offset of a 'Zap service call handler'. This code is called at
- various points to tell you about things. In general the entry/exit
- conditions are:
-
- \E R1=reason code and other registers may hold data.
- R11=undefined
- R12=Zaps workspace pointer as usual.
- \X You should preserve R1-R13 unless otherwise stated.
- R0 and flags may be corrupted.
-
- The (current) service calls are listed below. You should ignore unrecognised
- values in R1 so I can add more if necessary.
-
- R1=0
- Zap is quitting and about to kill your module. Return R0=-1 to stop it.
- Your module will NOT be automatically killed if have no service call handler
- (for backwards compatibility).
-
- R1=1
- Zap is just about to start up your command table.
-
- R1=2
- Zap has started up your command table. You should use this call to claim any
- workspace via Zap_Claim. (This is usually called directly after R1=1).
-
- R1=3
- Zap is deleting a file. R9=file block of file being deleted. (See E-File)
-
- R1=4
- Zap is deleting a window. R8=window block of window being deleted.
- (See E-Windows)
-
- R1>=&8000
- Zap has received an unrecognised wimp message that you may want to act on.
- The message is broadcast to all modes and command tables. Please IGNORE (ie
- return) unless you understand the message number and the window handle!! Use
- this to enable moving (via Wimp_OpenWindow) of your own windows!
- \E R1=message block pointer (as sent by wimp)
- R2=R1!16=message number if R3=17 or 19
- R3=message type
- (Null requests are scheduled - use Zap_CallBack)
- 1=redraw window request for unrecognised window
- 2=open window request for unrecognised window
- 3=close window request for unrecognised window
- 4=pointer leaving unrecognised window
- 5=pointer entering unrecognised window
- 6=mouse click on unrecognised window
- (Drags dealt with by Zap - use Zap_DragBox)
- 8=key press for unrecognised window
- (Menu clicks handled automatically - use Zap_OpenMenu)
- 10=scroll request for unrecognised window
- 11=lose caret for unrecognised window
- 12=gain caret for unrecognised window
- 13-16=passed straight on (not recognised by Zap)
- 17=unrecognised user message (or recognised message applying
- to unrecognised window)
- (type 18 gets passed on as 17 as well)
- 19=unrecognised bounced message
- 20+=passed straight on (not recognised by Zap)
-