SYSTEM DEFINING WORDS
Consider this chapter as a model application even if you are not actually interested in the details of the system application.
You have been introduced to writing colon definitions in MVP-FORTH as well as the idea that all definitions are located in your system's memory in a "dictionary". You have been told that each entry contains a variety of information. Let us now examine that a little more closely.
Each entry has a header, and usually some data. As pointed out, the header includes a count byte indicating the length of the name, a link to other words in the dictionary, and a pointer to machine code which tells the system what to do with the data which follows.
A colon definition is unique in that the pointer to machine code tells the system to execute each of the two byte pointers which follow in a sequential list. The data in a colon definition is a simple array of pointers. The array ends with a pointer to the function, EXIT. This function terminates a colon definition. There are a few exceptions to this rule about which you will learn more later.
With a colon definition we can include any word already defined or any numerical value currently acceptable to the system. This is certainly the most common type of defining structure in MVP-FORTH. A colon is used to start the definition and a semicolon is used to terminate it. The colon is really a MVP-FORTH function which creates a word in the dictionary and prepares to build the array of pointers to the functions to be executed. Rather than entering the function EXIT, the semicolon enters that for you in just the right place.
There are several other types of defining words besides colon. You have already seen constants, LIMIT for example, and variables such as the user variable BASE. The MVP-FORTH words CONSTANT and VARIABLE are also defining words. They are available for your use.10 CONSTANT TEN VARIABLE VALUE
Each of these lines will add a word to the MVP-FORTH dictionary. The first one has the property of giving the system a value every time it is executed. TEN will now give the value 10 without going through a number conversion. It will run much faster than a number conversion.
A VARIABLE will give not the value but a pointer to the value. The data field contains the value. Note that the content of a variable is not initialized when it is defined. Your program must initialize the value.
The advantage of having two ways of defining numerical values is a matter of convenience. Each can do much the same thing. If you are always going to have to get the value of a variable and it may change frequently you will find it easier to use VARIABLE in defining the word. If, on the other hand, the value is going to remain fixed, you will probably find that CONSTANT is better to use in defining the word.
Next you will have to learn to put values in variables and to get values from the variables. MVP-FORTH speaks of these functions as 'store' and 'fetch' respectively. The notation is cryptic. An exclamation point ( ! ) is used for 'store' and the at symbol ( @ ) is use for 'fetch'. The 'store' function is particularly powerful and thus particularly dangerous.
At this point you now have the power to make a mistake and destroy your system. You will have to learn to be responsible. But even if you destroy your system, all is not lost if you have developed good work habits. Always maintain a backup copy of your work.
The worst part of making a mistake using the 'store' function is that you do not recognize that you have done it. You have inadvertently stored an unknown value in an unknown location. Not until sometime later will a problem show up. It will show up when the location you have modified is used by the system. This may occur immediately. But it may also occur hours later. In that case you will not even be thinking about a mistake you may have made in the past.
As a consequence, do not be overly disturbed if your system quits working for you or does very peculiar things. Perhaps you are not perfect and some time ago made a mistake. Rather than try to debug the system, go back to a copy which you know is good and start over again. Perhaps a quick look to see if your new routine is correct is worth while. But before spending too long be sure that it is your current new routine which is causing the trouble.
Hopefully, the point has been made: be a responsible programmer and you can enjoy the power of FORTH. You will probably have to learn this by experience.
The functions 'store' and 'fetch' operate with 16-bit address values as well as 16-bit data values. Thus two bytes are accessed beginning at the designated byte address. There are two other functions, ' C-store' ( C! ) and 'C-fetch' ( C@ ), which operate on 8-bits at the designated address. The "C" is mnemonic for character.
All this aside, you were learning to manipulating variables. When you give the name of a variable, the system finds a pointer to the variable. To find out what is in the variable you must 'fetch' the value.VALUE @ .
And to display it, you will have to print it with 'dot'. Before the content of the variable VALUE has been initialized, you will fetch garbage. To initialize a variable or to later place a value in the locations:100 VALUE !VALUE @ .
You have stored the value 100 at the location pointed to by VALUE. You have then inspected the new value. You could have used another MVP-FORTH function to inspect a value:VALUE ?
The question mark has been defined as 'fetch' and 'dot'. It takes one less stroke. The function has a long history in FORTH but not everyone uses it regularly. Again it is left up to the user.
At this point, try changing a value in a constant such as LIMIT. This exercise was avoided earlier because you should have some comfort with MVP-FORTH before using it for things like this.
MVP-FORTH has a function which will search the dictionary for the word which follows and return a pointer to the beginning of the data field if it is found. The data field is sometimes referred to as the parameter field.' LIMIT @ .
The apostrophe by itself is called 'tic'. It will search the FORTH dictionary and return a pointer to the data field. There are several ways you can inspect the contents of a data field. If you know that the word's data field contains a numerical value you can fetch the value and print it. That is what you did above.
Now that you know how to change the value of a constant, you can increase the size of your MVP-FORTH image in memory. To do this you have to know something more about your system. You will not want MVP-FORTH to write over some other necessary resident part of your system. You will have to refer to your system documentation to determine a safe value for LIMIT. As a sample and probably safe value for LIMIT you could use 32000.32000 ' LIMIT !
Having changed the value of LIMIT you need to recreate the high part of MVP-FORTH in the system's memory. This is done by reconfiguring the system.CHANGE
The function of CHANGE is to restart FORTH using the current value of LIMIT. Later you can change other properties of the system with CHANGE.
After executing CHANGE you will have lost all of your new definitions unless you take particular care to save the current status. The problem is that in low memory are kept a number of start-up values such as the location of the top of the dictionary. Before you execute CHANGE, execute FREEZE. The function of FREEZE is to save all of the current system status values in the proper location in low memory. Once this is done CHANGE will use the current status values.
You could use 'tic' to return the data field for the variable VALUE as well. But it is not necessary because it is the same thing that is returned by a variable.VALUE ' VALUE . .
Demonstrate for yourself that this is true.
You can also use DUMP to examine the data field of any FORTH word.' LIMIT 10 DUMP
This function not only displays the contents of the data field of LIMIT, but 16 bytes beginning with it. DUMP will always fill out a row. Now comes some possible confusion. When 16-bit values are stored in memory, many eight-bit systems store the least significant byte before the most significant byte.
If you did not modify the value in LIMIT, you will see the first byte is 00 and the next one is 60. The values are in hexadecimal and the 60 comes before the 00 making the value 6000 hexadecimal. The remainder of the data displayed with DUMP begins the header for the next word in the FORTH dictionary.
You can now change the data for the calculation used to access the disk with the 'fetch' and 'store' functions. You might need to change the data used by the system to find the selected information on the disk.CONFIGURE
A carriage return will abort this function with no change to your system.
The information displayed in the prompts for CONFIGURE are never accessed by the system in accessing the disk. In fact not all of the information is always used. It depends upon the implementation.
The data is arranged in arrays for each of the available parameters. The arrays are blocks-per-drive ( BLK/DRV ), sectors-per- track ( SEC/TR ) and sectors-per-block ( SEC/BLK ). Now you can inspect these arrays.BLK/DRV 10 DUMP
The array is composed of 7 16-bit values arranged in order according to the density codes 0 through 6 selected with CONFIGURE. That is, each value uses two bytes. Remember that many systems place the low order byte first. Also remember that the display of DUMP is in hexadecimal.
Examine each of the other arrays in a similar manner.
CONFIGURE allows you to select the number of drives your system has and to assign one of seven density codes to each drive ( 0 through 6 ). The code you select for a specific drive accesses the data from these arrays as necessary. If you have only one type of drive and drive density, you can assign the proper information to the first item in each of the arrays. Then in spite of the prompt, when density code 0 is selected those values will be used.
Perhaps this exercise has moved ahead of your experience. If your system is working and the disks are being properly accessed, you will have no need to make any changes to these arrays. However, you might have found it interesting to see how they are laid out.
How do you put the values into the arrays? To create an array you can start with the definition of a variable, then instead of a new definition, you can simply add a series of values to the dictionary.
The system maintains a dictionary pointer, DP. You can display the value at DP by the MVP-FORTH words HERE 'dot'.HERE .
There are two functions which add values to the dictionary: 'comma', and 'C-comma', ( , and C, ). The comma will add a 16-bit value to the dictionary and advance the value in the dictionary pointer 2. HERE will then return a value two larger. The C-comma will add an 8-bit, character, value to the dictionary and increment the dictionary pointer only one address.
Thus you could make a new array of 7 values:VARIABLE TEST-ARRAY 0 TEST-ARRAY ! 0 , 0 , 0 , 0 , 0 , 0 ,
Now inspect what you have done.' TEST-ARRAY 10 DUMP
If all is well, you will see 14 bytes of 0. You are beginning to get the feel of using FORTH.
An alternate way of creating an array of 7 16-bit values is:VARIABLE TEST-ARRAY-2 12 ALLOT
Execution of VARIABLE in defining the word allots 2 bytes for the value. You need to ALLOT 12 more bytes in your dictionary for the rest of the values. With this method, the values are not initialized.
Now to access an item in the array, you need to select an item number. Remember the first item will be 0. Then double the item number because each item takes two bytes, and add that to the pointer returned by the variable TEST-ARRAY. You now have a pointer to the desired item in the array, so fetch the value there.4 2* TEST-ARRAY + @ .
This sequence will inspect the 4th 16- bit item in the array TEST-ARRAY.
If you are going to do this often, you might define an appropriate pair of words.: @TEST-ARRAY ( item --- ) 2* TEST-ARRAY + @ ; : !TEST-ARRAY ( n, item --- ) 2* TEST-ARRAY + ! ;
You have combined two FORTH mnemonics for the name of each function. In both cases you need to tell the system which item you are accessing.
At this point you have explored three types of defining words: colon definitions, CONSTANTs and VARIABLEs. There are other kinds of defining words and you can easily write your own, but you will have to wait for that.
You have also learned one way to create arrays and to 'fetch' and 'store' values from them.
Next Previous Contents