Finding new words in AMPLE

Kevin Doyle
AMPLINEX members who read the Feature in AMPLINEX 008 by Tony Walduck will know that all AMPLE words are stored in memory as tokens much as the words in BASIC programs are. In his feature, Tony identified the tokens which corresponded to each of the user-accessible (UA) words available in the AMPLE Nucleus. It was clear from his notes, however, that a lot of tokens were not used for such words.
Anyone examining the contents of AMPLE modules (rather than user programs) will notice that some tokens are used which are not in Tony Walduck's list - i.e. which are not UA words. These non-UA AMPLE tokens allow the modules to perform tasks which are impossible with only the UA words. The same observation applies the AMPLE Nucleus ROM itself, which it written, in part, in AMPLE.
Recently, in order to write a utility, I examined the use of some of these tokens and, by trial and error, worked out the function of a few of them. For the benefit of those who may also wish to extend their AMPLE programming range, this article introduces some of the ways in which these non-UA features can be used.
Since such tokens are not accessible through a user word, a way has to be found to write the token value directly into a user program. This can be done by the careful reading and writing of bytes in a user program in memory, but this is rather awkward, and liable to error.
In addition, since such tokens cannot be translated back into a user word via TYPE or WRITE, editing such programs within AMPLE is impossible.
To get around such problems, I decided to write my utility program in a word processor and EXEC it into AMPLE. This way I could write the program, then try it in AMPLE, with no danger of corrupting the program in the process.
This also meant that I had to find a way of introducing a token into a program via an EXEC file.
The technique I decided to use, was to define some new words to contain each of the tokens required. I initially defined the word using GVAR, for example,
"test" [GVAR]
The reason for using GVAR is that it returns an address which refers to two bytes located immediately after the GVAR token, within the word definition, which are normally used to store the value assigned to the word. The memory map looks like this:
00 01 02 03 04 05 06 07 08 09
-----------------------------
74 65 73 74 nn 00 12 lo hi 20
 t  e  s  t    [    GVAR    ]
where 'nn' is the user word token, and 'lo' and 'hi' are the two bytes which store the GVAR value.
The fact that GVAR returns an address which is at a known position in the user word means that it can be used to allow the contents of the user word to be directly altered in memory.
In the above example, typing 'test' will return the address of the 'lo' byte in the word definition.
We can thus obtain this address, and overwrite the token for GVAR with a new one. This still leaves the other two bytes - 'lo' and 'hi'. I decided to overwrite these with the token for a comment (&0F) and a zero (which would be regarded by AMPLE as indicating a comment of zero length).
So, the following definition would allow the word 'test' to be set up with a token value of &60:
"test" [GVAR]
15 test #! &60 test 1 #- #B!
giving a memory map like this:
00 01 02 03 04 05 06 07 08 09
-----------------------------
74 65 73 74 nn 00 60 0F 00 20
 t  e  s  t    [      %     ]
Having devised a way to set up words to contain the tokens I required, I began to test the tokens I had seen in use in the modules to find their effects. The utility I was writing was one which would identify user words which were not used elsewhere in the program - to show which ones might be able to be deleted.
I discovered four tokens which I needed for this program: &2E, &59, &73, and &B8.
Defining their operation was a matter of trial and error, but I think the following descriptions are correct.
&2E - returns the address of the next occurrence in a word definition of a specified token. Thus, it can be used to check whether a particular word contains another word.
number address &2E -> address ON
                   -> OFF
It takes a number (which is the token to be searched for), and an address for the start of the search. The search ends when the end of the word definition is reached. If the number is found, &2E returns the address of the occurrence, and the ON flag. If the number is not found it returns the OFF flag.
&59 - pulls a word name string from a specified address. Thus, if the start address of a word definition is known its word name can be found.
address &59 -> namestring
The byte before a word name in a definition contains the value &80 + the length of the name. Thus the word 'test' would have the value &84 in the byte preceding the word name. The address of this byte is passed to &59 and it returns the word name string.
&73 - returns the address of the start of the next word, alphabetically. This can be used to step through the list of user words in sequence.
address code &73 -> address OFF/ON
It takes an address of the start of a word, or 0 to find the first word. The code is set to 6 for user words - I do not know the meaning of other values. The address returned points to the next word in ascending alphabetical sequence (as displayed by SHOW) and the OFF flag. If there are no more words the input address is unaltered and the ON flag returned.
&B8 - pads out a word name string to a number of characters which allows a columnar display, and prints it to the screen.
string &B8 ->
If the number of characters in the string is greater than 9 the string will be padded with spaces to the right to bring it up to 10, 20 or 40 characters, whichever is the next highest of these figures. It then prints the result to the screen. It is used by SHOW to display a list of user words.
Having identified the operation of these words I used them to write a small utility to show unused words. This was published in AMPLINEX 013 (Utilities section) and an annotated version of the program is included on this disc to illustrate the use of the words described above.
The utility takes each user word in turn and checks for its occurrence in each user word in turn. Those words which are not found in any other words are displayed on the screen.
The challenge I would like to offer AMPLINEX members, however, is to identify more of these non-UA tokens in order to build a base for more extensive use of the AMPLE language.
There are over 80 tokens undefined in Tony Walduck's list. For those without a copy of AMPLINEX 008, there are no user-accessible tokens between &72 and &82; between &99 and &A3; and between &F4 and &FF.
One word of warning - do not try out these tokens with any program that you have not already saved, as many of them may corrupt memory!
Happy hunting - and don't forget to let AMPLINEX know your results.

Related file on this disc:
F.NWdemo - annotated utility to show the use of AMPLE words not normally accessible

Published in AMPLINEX 017, May 1990