There is no way to write a general guide to all of the assemblers necessary for all of the different processors running MVP-FORTH. If you want to use an assembler, you will have to refer to appropriate materials for the processor in the system you have.
The several MVP-FORTH assemblers use the mnemonics which are standard for the system upon which the particular implementation is designed to run. How can one say anything in general? Well there are some things in common.
To define a word in the FORTH dictionary which will run the machine code generated by an assembler, a special header structure is necessary.
The problem is to create in the dictionary a header structure in which the code field contents points to machine language beginning in the data field. That machine code must end with a jump to a location known as NEXT in the object code of MVP-FORTH. In MVP-FORTH, that address is contained in a constant NEXT.
In 8080 machine code you could create a machine code routine which does nothing as follows:HEX CREATE NOOP HERE DUP 2- ! C3 C, NEXT , DECIMAL
Between the ! and C3, you could 'comma' and 'C-comma'in any machine code sequence you wish. You would be working back before the days of assemblers. The exercise is a good one to understand what you are doing but really not all that practical.
The source code for the assembler in your implementation of MVP-FORTH is available for your use in the MVP-FORTH User's Manual and on the FORTH screens disk provided. You will need to refer to that specific documentation. There are, however, some general comments. Included with the floating point application is a more complete ASSEMBLER.
The ASSEMBLER is a vocabulary in your implementation. To use it, you must call upon the ASSEMBLER. Remember that all vocabularies are flagged as IMMEDIATE. This means that you will have to make a special effort to compile it within a colon definition.
ENTERCODE is an MVP-FORTH primitive whose function accomplishes that and provides a check value for one level of security. This function can be used in two places. There are two common ways to start assembly code: 1/ terminate a colon definition and continue with a machine code sequence which is the function of ;CODE , and 2/ create a new definition which is exclusively machine code and is the function of CODE . Both of these possibilities call upon the function of ENTERCODE.: NOOP ;CODE NEXT JMP END-CODE CODE NOOP NEXT JMP END-CODE
The above sequences have the same function. They each create a header structure in the FORTH dictionary. Both functions end up doing nothing. Examine the source code for your assembler.
In MVP-FORTH, assembler functions defined through the use of ENTERCODE must always terminate with END-CODE. This is necessary to execute the security included in the defining words. Only if the security is met, will the smudge bit in the newly defined word be toggled off.
In order to place the assembler words in the ASSEMBLER vocabulary, you need to use;ASSEMBLER DEFINITIONS
The structure of any assembler in FORTH takes advantage of a family of defining words. In all assemblers, an op-code may take none, one or more operands. The various op-codes fall into groups or types. A defining word for each type is first written. The number of types varies among assemblers. With these defining words, the specific assembler mnemonics are defined as words in the FORTH ASSEMBLER vocabulary.
You will need to examine your MVP-FORTH User's Manual to understand exactly what is being done. You will note that extensive manipulation of the values given the system is done by most of the defining words. As usual in FORTH, the system needs to know the values before receiving the actual command. All Forth assemblers require the parameters before the assembler function, rather than after as in conventional assemblers.
About the only way to master the use of a FORTH assembler is to examine code written with one. A number of the implementations in ALL ABOUT FORTH are given using an 80x86 FORTH assembler.
You will find one problem in the examples in ALL ABOUT FORTH. They were interpreted by a FORTH cross compiler which could do forward referencing. That is, you could refer to an address with a label and only later define the label. The need to do this is handled in a different way in most FORTH assemblers.
The need for forward references in assemble code has to do with a variety of structures. These structures include conditional forward jumps and loops. These structures resemble the conventional ones in FORTH and are given the same name but with different functions in the ASSEMBLER vocabulary.
By examining those definitions in your assembler source code you can see how they operate. An alternate way is to really understand the machine code for your system and keep track of values yourself. In some ways this is the quicker way to a solution for one already experienced with the various conditional jumps.
The execution of assembler mnemonics in the ASSEMBLER vocabulary actually compiles bytes into the FORTH dictionary with 'comma' and 'C-comma' in the defining words. At all times the rest of the FORTH vocabulary is available. Of course you will have to exclude those structures whose functions are different in the ASSEMBLER vocabulary.
Where you want a label for a forward reference, you can save the location with HERE and give the system a dummy value. If the value goes into an address following a conditional jump, you will have to increment the value found by HERE. When you get to the location to which you want to do the conditional jump, you can get its location with HERE and store that address in the previous address.... HERE 1+ FFFF JNZ ...... HERE SWAP ! ...
All of this requires understanding what you are doing. This is not designed as a tutorial in assembly language. Rather, you might find some guidance in techniques to explore.
Try taking a tutorial for the assembler language for your machine. Start at the beginning and implement the examples in FORTH. When you can make the transition, you will have mastered your machine!
Would that there were an easier method to master the use of machine language.