Most computer languages restrict the functions available to previously defined routines. In many applications you might find it desirable to change the functions. To use a new function, you might have to recompile your entire program.
What you would like is a way of changing a selected function and have the new function used every time the old one is referred to in the already completed part of the program. An example of this is the MVP-FORTH word PAGE.
The function of PAGE is to clear the screen and home the cursor. The code necessary to do this is usually different from one terminal to the next. If you have a generic MVP-FORTH Programmer's Kit version, you will find that PAGE does not perform as defined. Your documentation will tell you how to proceed but you will see how vectoring PAGE is a big convenience. You can write the necessary program and vector PAGE to it.
The generic MVP-FORTH Programmer's Kit version vectors PAGE to CR . The run time routine of a carriage return seems safe enough even if it does not do what you want. You must now find the escape sequence or code necessary to do the desired function.27 EMIT 69 EMIT 26 EMIT 3 0 0 0 16 INTCALL DROP
On various systems one or another of the above routines serves the desired purpose. EMIT causes the preceding byte value to be sent to the monitor. The first line sends an escape code followed by an upper case E. The second sends a control-Z to the monitor. Finally, after setting up the necessary values, the last line does an interrupt call which is possible on some systems. It is beyond the scope of this guide to cover all of the possible codes.
You can test the possible functions as indicated above. When you find one that works, put it in the dictionary as a new colon definitions.: <MY-PAGE> 27 EMIT 69 EMIT ;
Next you can verify your new definition. FORGET and modify it as you find necessary.
You are now ready to vector the new definition into your system. A group of variables has been assigned names combined with a preceding apostrophe. These variables contain pointers to the respective execution addresses. For PAGE there is 'PAGE. The function of PAGE is simply to get the pointer from 'PAGE and EXECUTE it.
EXECUTE is an MVP-FORTH function which will execute the word pointed to by the value previously given. That is, one can give the system the address of the pointer to the code routine for a given word and the EXECUTE it.
PAGE is defined as follows:: PAGE 'PAGE @ EXECUTE ;
Other vectored functions work the same way.' <MY-PAGE> CFA EXECUTE
This will be another way to test that the value you are going to put into 'PAGE is correct. Remember! In MVP-FORTH, the address returned by a 'tic' is the address of the beginning of the data field, which is sometime referred to as the parameter field address of a word. The pointer to the machine code used to interpret the data is two bytes before the data field. It is known as the code field address, ( CFA ). A FORTH function, CFA, decrements the data field address two bytes. This then is the address to be executed.
You can now put the code field address of <MY-PAGE> in 'PAGE.' <MY-PAGE> CFA 'PAGE !
Hence Forth PAGE should perform as expected.
Note: Since parenthesis is used with comments, MVP-FORTH uses angle brackets to enclose many primitives.
Vectoring can be used in a variety of other ways. Suppose that you wish to have all of the alphabetical characters input from the keyboard in upper case even if you have not set the cap-lock key. MVP-FORTH gets all input from the keyboard with the function KEY. KEY is vectored to the code field address pointed to in 'KEY. In MVP-FORTH, 'KEY points to the code field address of a run time routine, KEY. All you need to do is check the value input by KEY and if it is a lower case character, subtract a hexadecimal value of 20 from it. If it is not a lower case character, do nothing more.
You can easily build an array for translating the ASCI values from the keyboard to Dovorak values and convert your system.
Exploring this problem will allow you to examine a few more MVP-FORTH functions. Perhaps you will want to develop this program on a scratch screen so that you can modify it as you debug your function.
First you will want to know what the code values for a lower case "a" and "z" are. You could go find them in a table somewhere, but why bother. You can easily check at the keyboard. Use the function KEY before you modify it.KEY <cr>
The system will wait for you to enter any key at the keyboard. You can then see what that key was with a 'dot'. Use this function to determine the value of lower case "a" and "z". All codes within this range should be changed by reducing the value by a decimal 32 or hexadecimal 20.: <UPPER-KEY> DUP 97 < OVER 122 > OR 0= IF 32 - THEN ;
Several new MVP-FORTH functions have been introduced. You will learn more about them later, for now just use them. The new function first executes the original run time function to get a value. You will not want to use the word KEY, because you will eventually change its meaning. You then need to use the values you determined for lower case "a" and "z". First make a copy of the value returned by <KEY>. Then enter the code for a lower case "a" and make a logical comparison. A truth flag is left. Next save that flag and get another copy of the original value and see if it is above a lower case "z". You then have two truth flags which you combine with the logical operator OR. Finally you reverse that flag which says that the value is not out of the desired range. You can then apply the MVP-FORTH conditional structure IF ... THEN. More on this later.
You may find that FORTH is easier to read than English text.
The purpose of this exercise is to illustrate vectoring and not all of the code necessary to make all alphabetic characters upper case.
You can try your new function.<UPPER-KEY> <cr> EMIT
The new function will wait for a key and then EMIT will cause the symbol for code which was left to be displayed on the monitor. When you are convinced that the new function is working correctly, you can vector it into KEY.' <UPPER-KEY> CFA 'KEY !
Now you no longer have to worry about having the capital lock key set.
You can use vectoring for a number of other functions. They are suggested as exercises. Suppose you wish to keep track of the number of lines you are using. You could define a variable as a line counter. When you are ready to start set it to zero. Then define NEW-CR to increment the counter before executing the run time function <CR>. Finally, vector the code field address of your NEW-CR into 'CR.
Perhaps you will then want to execute a form feed each time you have output 60 carriage returns. Now you can put some logic into your NEW-CR. If the value in the counter is 60, output a form feed and reset the counter to 0 before completing the function. You can then vector that into your system.
There are many features of MVP- FORTH which you can change without having to completely rewrite the source code. You can add your new vectored functions.
Vectoring is particularly useful for forward referencing in developing you programs. You can temporarily vector in the code field of a NOOP function, if you have one. If not, define one. Later, when you define the actual function you can change the code field address in the pointer variable to the correct function.
If you have done any changes of the initial vectored functions you may well have a problem with FORGET. Suppose at some time you decide to FORGET all of your new definitions back to the beginning of your program. Should you have revectored a function in your program you will have forgotten the run time routine you defined. The amusing thing is that the system may not notice at first. Not until you reuse the area of memory which you freed by FORGET, will the system notice. But then you will find that you have vectored to something other than the intended function. In all likelihood the system will crash.
Vectoring is most useful in program development. Learn to use it effectively.
Next Previous Contents