CHAPTER 9. ADVANCED UTILITIES 9.1. REBUILDING THE SYSTEM If you need to change a parameter or function in the F-PC system, you will need to re-compile F- PC and/or KERNEL. This is simply done with the provided batch files as follows: C> FMETA Re-compiles KERNEL.COM C> EXTEND Re-extends to create F-PC.EXE Either of these may be performed from the keyboard while in DOS. FMETA invokes F-PC, loads the meta compiler, and recompiles the kernel. The resulting new kernel is stored back as KERNEL.COM. Utilities and applications are then compiled on the top of KERNEL by EXTEND to generate a new F-PC system. To extend the F-PC system with your application, edit the F-PC.SEQ file to include FLOAD instructions to load your application files. You may want to change the name of the EXE file finally saved. This can be done by editing the filename after the SAVE-EXE statement in F- PC.SEQ file. Meta compilation the the darkest art in Forth. Do not be fooled by the above simple discussions to think that meta compilation can be practiced easily. You have to understand F-PC completely to made modifications in the kernel files to rebuild a Forth to your own liking. Only Tom Zimmer is entrusted to make modification to F-PC. Nevertheless, you have all the source code and the tools to roll your own Forth in F-PC. 9.2. TURNKEY SYSTEMS The word TURNKEY and some associated words are included in the file SAVESYS.SEQ. TURNKEY is used as follows: ' MYAPPL IS DEFAULT TURNKEY MYAPP After completing an application compile, the word MYAPPL is defined to be performed by the program name MYAPP.COM. TUNRKEY automatically sets up the proper memory management to allocate 64k for your program, but does not save the heads. Minimum initialization is performed. A file specified on the command line will be opened, and you can use BL WORD to pick up additional parameters from the command line. You will of course not be able to interpret, since heads are not saved, and your application will need to handle all errors and return to DOS when the program completes. Before attempting to build an application, you will need to make a copy of F-PC.SEQ, for customization. Many of the later files in F-PC.SEQ are utilities, and will not be needed in your application. Start by writing your program and compiling it on F-PC.EXE. Work in this environment until you are sure your program works. Now insert your program filename into the copy of F-PC.SEQ you made, about half way down, and try to compile the copy of F-PC.SEQ. If it compiles then you can move your application file lower, until you have determined what utilities are needed by your application. Strip out all files above your application file, and load the file SAVESYS.SEQ. Use TURNKEY as previously described to make an executable .EXE file. TURNKEY allow you to customize F-PC to build an independent application, which may not allow the user to see the internal of the application. If you are not so protective, a more convenient way to generate an application is to use FSAVE, which saves the core image of F-PC after you have loaded your application. F-PC is included inside your application and the user have access to the entire system. This is a useful tool as you can make a snapshot of your current system, save it to the disk, and have it available the next time you resume your work. The commands are: FSAVE MYSYSTEM A file MYSYSTEM.EXE is saved in your current directory which contains everything you compiled so far. Next time when you execute MYSYSTEM under DOS, your current system will be loaded and F-PC will be at your service. 9.3. MACROS IN F-PC AND SED A file called MACROS.SEQ is provided,. This file implements keyboard macros in Forth at the level of KEY. These macros can therefore be used in the editor also. The macros are used as follows: (the sequence "Alt-M" means hold down the "Alternate" key and press the "M" key.) Alt-M Start defining a macro. Alt-1 We are defining the Alt-1 macro. Enter any keys you want in the macro, up to 128 keys. Alt-M Complete the definition of the Alt-1 macro. Any keys available on the keyboard except Alt-m, and Alt-1 to Alt-5 can be included within a macro. To execute a macro, simply type its key name: Alt-1 Execute the macro key sequence for the Alt-1 key. Currently macros may be only 127 characters in length, although this can be changed by modifying the constant MAXMAC and recompiling the system. See the example in Appendix B-3. 9.4. F-PC PREFERENCES While F-PC may seem like a nebulous glob of stuff, some things about it can be adjusted fairly simply. The install process, for example, allows you to tell F-PC where its source file will be located, whether you want to have backup copies made of your edited files, and what you want to call your installed version of F-PC. There are however a number of other things you might like to adjust to your personal way of doing things. Here is a list: The status line display may be turned on/off. STATON Enable status line display at top of screen. STATOFF Disable status line display. The decompile display during debugging may be turned on/off. SRCON Source display enabled during debug. SRCOFF Source display disabled during debug. The default file extension for the system and the file specification string for the popup window file selector may be changed. DEFEXT Default file extension string. HIDDEN DIRSPEC$ Directory specification for popup window. The format of date printing can be adjusted to one of the three supported formats, or you can add your own. M/D/Y Month/Day/Year (default format) Y-M-D Year-Month-Day D.M.Y Day.Month.Year You can manually turn editor backups on or off without going through the install process. BACKUPOFF Disables the editor from making backup files. BACKUPON Enables the keeping of editor backup files. F-PC will automatically save any changes you made to a file you are editing, if you stop touching the keyboard for 10 minutes. AUTOSAVEON Turn on auto save. AUTOSAVEOFF Stop auto save. AUTOSAVE-MINUTES Value of minutes to wait before saving. Default is 10. Screen display output can be switched between DOS and Direct Video output for all screen text display. FAST Direct video screen write for all displayed text. SLOW Use DOS for all screen display. F-PC defaults to automatically entering the editor when an error is encountered during a file load. You can control this with the following words. AUTOEDITON Automatically enter editor on load error. AUTOEDITOFF Don't enter editor on load error. When an error occurs, the base for number conversions will be change back to DECIMAL. This feature can be turn off so that the base is not affect by errors. DECIMALBASE Change to DECIMAL after an error. HEXBASE Change to HEX after an error. NOBASE Do not change base on error. DEFBASE A value to restore base. 0 for NOBASE, 10 for DECIMAL and 16 for HEXBASE. User can choose his default base here. If you are using a CGA (Color Graphics Adapter) type of video display board, you will probably want to use BLANKON to reduce the amount of snow or sparkle on your screen. This word causes the screen to be blanked while text is being written to the display to reduce this effect. These words have no effect on monochrome display adapters. Use BLANKOFF for an EGA or VGA adapter. BLANKON Enable screen blanking during text output. BLANKOFF Disable screen blanking during text output. Most green or amber monochrome monitors display light characters on a dark background. If you have a color monitor or true white on black monitor you may want to reverse foreground and background, giving a page white look with dark characters on a white background. I have found this to be more comfortable for my own use. You might also try the BLACK-ON-WHITE mode with an Liquid Crystal or Florescent display. WHITE-ON-BLACK Normal, light chars on dark background. BLACK-ON-WHITE Invert the screen to dark on light. With a color monitor, F-PC can display different classes of words in different color. It is a very interesting demonstration to impress novice programmers when executing WORDS, SEE, or DBG. It is probably not very useful in normal programming because you cannot see very well words in blue and light grey. COLORIZEON Turn on colors in word list. COLORIZOFF Go back to work The number of screen F-PC will save on its screen stack if adjustable within the range 1 to 14. SVSIZE bytes (~4000) are allocated for each screen stacked. F-PC needs SVMAX to be at least three (3) for all of the existing utilities to function properly. SVMAX is a "VALUE" that can be changed with "=:". You will only need to do this if you write a program that needs to stack screens more than the default number of screen deep. 5 =: SVMAX \ increase number of buffers to 5 FSAVE F \ resave the system BYE \ leave after changing and saving F \ now the screen stack is 5 deep. Your preferences can be edited into the configuration file F-PC.CFG. This file is executed by F- PC immediately after it is loaded into memory. Only a few of the preferences were included into the configuration file during the installation/configuration process, and most preferences were set to default choices. In the hypertext root screen, a link item 'Preferences' is available for you to see all the possible choices on-line. 9.5. TASK CHAINING Tom Zimmer developed a very powerful technique by which more functions can be added to a word as the needs grow. He called it background task chaining. The idea is to use a DEFERred word as a basis. Some time later this deferred word is resolved to do one task. We can add some more tasks to this word by defining a new word and compiling the contents of the deferred word into the new word with other functions. The deferred word is then re-vectored to the new definition. When the deferred word is executed, new functions are added to the old task. This task chain can thus be extended to your heart's desire. The words involved in task chaining are: DEFER to define a deferred word whose function can be changed by re-vectoring, and DEFERS an immediate compiler word which compiles the contents of the next deferred word in a colon definition. It allows many functions to be added to the deferred word. In F-PC, KEY is a user deferred word. We have to use DEFERS to extend its function. BGSTUFF is a regular deferred word to extend functions like the status line display. BYESTUFF is used to extend the cleaning up task before F-PC exits to DOS. Let's use BGSTUFF as an example: DEFER BGSTUFF ' NOOP IS BGSTUFF : (KEY?) DEFERS BGSTUFF { the words to do (KEY?) } ; ' (KEY?) IS BGSTUFF \ BGSTUFF = (KEY?) : TIME DEFERS BGSTUFF #OUT @ #LINE @ \ save cursor position 64 0 AT .TIME \ print time at upper-right corner AT \ restore cursor ; ' TIME IS BGSTUFF \ BGSTUFF = (KEY?) + .TIME This technique allows you to dynamically change the behavior of a deferred word while keeping most of its old functionality. As the system grows, it is easier to add new functions to an existing word than to define new words and mess up the existing environment. 9.6. CONTROL STRUCTURE ENHANCEMENTS Bill Muench contributed a modified set of control structures. The changes are very very minor, but result in a significant increase in versatility. The change is effectively to move a 2SWAP from the beginning of REPEAT and put it at the end of UNTIL. Some additional words have also been added to take advantage of the increased versatility. The changes have been added to the system, the meta compiler, and the assembler. Some possible combinations of the structures are shown in the following cases. However, the possible combinations are only limited by your imagination. WHILE can be used to exit a DO...LOOP conditionally. The WHILE structure can be nested. DO ... WHILE ... WHILE ... LOOP ... ELSE UNDO ... \ drop or use index and limit THEN ... ELSE UNDO ... \ drop or use index and limit THEN A normal BEGIN..WHILE..REPEAT loop behaves like it always did: BEGIN ... WHILE ... \ normal structure REPEAT CONTINUE allows a conditional branch back to BEGIN: BEGIN ... IF ... CONTINUE ... \ now branch back to begin UNTIL \ otherwise, conditionally branch WHILE can also leave a BEGIN..UNTIL loop conditionally. BEGIN ... WHILE ... \ multiple exit tests UNTIL ... ELSE ... \ and possibly different action THEN WHILE can also be nested in a BEGIN..UNTIL loop. BEGIN ... WHILE ... \ multiple exit tests WHILE ... \ multiple exit tests UNTIL ... ELSE .. \ and possibly different action THEN ... ELSE ... \ and possibly different action THEN AFT..THEN structure can be nested inside BEGIN..WHILE..REPEAT loop. The clause inside AFT..THEN is executed only once in the first looping. BEGIN ... AFT ... \ executed only once THEN .. \ ignored afterwards WHILE ... REPEAT The FOR...NEXT structure was proposed by Chuck Moore in the cmForth for the Novix NC4000 Forth chip. FOR takes a count from the data stack and pushes it onto the return stack. NEXT decrements the count on the return stack. If the count becomes zero after being decremented, the loop is terminated; otherwise, the loop is repeated. The FOR...NEXT loop can also use WHILE to exit conditionally: FOR ... WHILE ... \ in effect an immediate ?leave NEXT ... ELSE ... R> ( DROP ) \ drop or use the loop index THEN AFT..THEN structure can also be nested in a FOR..NEXT loop. FOR ... AFT ... \ this is only executed the first \ time through the loop THEN ... \ this is executed every time NEXT Another way to exclude the n=0 case and also have the loop execute n times, but is longer and slower specifically on a FORTH machine like the NC4000 or Harris RTX. ( n ) ?DUP IF 1- FOR ... NEXT ... THEN BREAK allows the construction of a case structure in a colon definition: ... IF ... BREAK \ case like structure ... IF ... BREAK \ break compiles an exit ... IF ... EXIT THEN \ same as break 9.7. HEADLESS WORDS This is a neat utility from George T. Hawkins to allow the extraction and removal of the unwanted heads in the Forth system and any application you may write in F-PC. Any words to be later beheaded are identified with a "HEADERLESS" keyword. This is followed by the colon definitions or code words themselves. You re-establish standard words (i.e., words with headers) with the keyword "HEADERS". When you have finished your use/referencing of headerless words, you then use the keyword: "BEHEAD". This will completely remove the definition of any headerless words from the directory. Once headerless words are BEHEADed they are lost forever; i.e., their code and list space is not lost - but they are unknown so far as the dictionary is concerned. Note that you cannot ever reference a HEADERLESS word once it is BEHEADed. So the logic to using HEADERLESS words is as follows: ONLY FORTH ALSO EDITOR ALSO HIDDEN \ set up search order as needed HEADERLESS ... \ put headerless words here HEADERS ... \ put words which reference \ the previous group of \ headerless words here EDITOR DEFINITIONS \ switch to EDITOR vocabulary \ but don't change order. \ repeat above sequence of: HEADERLESS \ Turn off heads in editor vocabulary ... ... HEADERS \ Turn heads back on ... ... HIDDEN DEFINITIONS \ switch to HIDDEN vocabulary but don't \ change order. \ as desired BEHEAD Although the use of headerless words can save you head space, their main advantage is in the software engineering they provide. That is, the definitions/names are *completely lost* not just stashed away in some obscure vocabulary. (If you attempt to "see" or "debug" headerless words through regular words you get a garbage ID.) In general you should set up your {HEADERLESS/HEADERS}/ BEHEAD definitions as described above, but precede it with a single "HWORDS-". HWORDS- will cause HEADERLESS, HEADERS, and BEHEAD to be treated as noops. Once you've finished debugging and are ready to go to production, then change "HWORDS-" to "HWORDS+". This will give the HEADERLESS, HEADERS, and BEHEAD words their standard meaning. If you ever need to debug the code again, and want to see the names, then change HWORDS+ to HWORDS-. As can be seen in the above example, you should setup your vocabulary search order prior to starting a sequence of definitions in which some words will be headerless. After setting the search order, you can still select different vocabularies in which you place definitions, but you MUST NOT change the search order, that is you MUST NOT use "ONLY" or "ALSO". Also the current vocabulary should not be changed while in HEADERLESS mode. 9.8. SAVE AND RESTORE At times one needs to change various global attributes of the Forth system while preserving their value to be later restored. An example of this might be changing CAPS to ON, while saving its current value to restore later. Here is a typical code segment to save CAPS, turn it on, and restore it at later in a definition: : DEF1 ( --- ) CAPS @ >R CAPS ON \ Save CAPS and turn ON ... use SEARCH for something ... ... R> CAPS ! \ restore CAPS ; While this is an acceptable way to save and restore a variable, it is difficult to read, and not particularly efficient in terms of performance. A new mechanism has been introduced which enhances readability, and improves performance at the same time. Here is an example of SAVE!> and RESTORE>: : DEF1 ( --- ) TRUE SAVE!> CAPS \ save and set CAPS ... use SEARCH for something ... ... RESTORE> CAPS \ restore CAPS ; These words allow a VARIABLE or VALUE to be saved for later, and set to a new value for temporary use. Another word included in the set allows saving a VARIABLE or VALUE without changing it, for later restoration: : DEF1 ( --- ) SAVE> CAPS \ save CAPS ... do something that may change CAPS... ... RESTORE> CAPS \ restore CAPS ; The only problem with these words is they cannot be use with user variables, as they are fairly dumb and fast. They simply work with the contents of the body of the definition following. 9.9 LINE EDITOR F-PC provides a very nice general purpose line editor for use in your application programs. It allows you to request a line of input from the user, while allows him to edit the text before pressing to send it to the program. The word to invoke it is LINEEDITOR. Its usage is as follows: 20 8 MYBUF 22 LINEEDITOR ( -- f ) In this example, the text buffer will start at column 20 of row 8. Editing will be performed on the counted string in MYBUF, and the maximum length allowed is 22 characters. The line editor is terminated by either or ESC key. If the ESC key is pressed than a false boolean flag is returned; otherwise, a true flag is returned. A mouse can be used to position the cursor within the edit line. If the editing is completed with , then the edit string is placed back into MYBUF. If the editing is terminated with ESC, then MYBUF will contain the original string unmodified by any edit operations performed during the editing session. During editing, you can use the Right arrow, Left arrow, Home, End, and Delete keys to position the cursor to edit the string.