ANTIC VOL. 2, NO. 6 / SEPTEMBER 1983 / PAGE 76
Traditional | Forth |
---|---|
LDA 712 | 712 LDA, |
STA COUNTX | COUNT ,X STA, |
INX | INX, |
Read the INX, instruction as "compile the opcode for the Increment X instruction." Note that Forth instructions require the operand to precede the operation. In the second example above, COUNT has been defined previously as a constant, so that its address appears on the stack before the indexed store command is compiled. The display list example contains a standard ATARI assembler listing which is the equivalent to the Forth word GR7DLI; it demonstrates the "backwards" instruction coding and a comparison of control structures.
In traditional assemblers, the instructions which control program execution are limited to Branch and jump group of insructions. Since there is no label field in Forth assemblers, jumping around inside a definition is not possible. In making up for the lack of a label field, the Forth assembler allows for many more ways to control program flow. The IF..ENDIF and IF..ELSE..ENDIF can be used to control execution based on the tested status of the Sign, Overflow, Zero, and Carry flags. Operation of these words is identical to the same structure in Forth. Other Forth control structures which are repeated in the Forth assembler include BEGIN..UNTIL, BEGIN..WHILE..REPEAT, and BEGIN..AGAIN. These combine to create a powerful set of control structures which greatly simplify programming.
You must know the rules of parameter passing to use the Forth assembler. Follow these rules whenever you use an assembly language definition along with other Forth words. The most important rule is that the X register must be preserved. It is the pointer to the top of the parameter stack and should be manipulated only when changes to the stack are desired. The second rule is that every assembly language definition must end with an appropriate re-entry jump; these jumps link the assembler definition with the rest of Forth. Of course, if a subroutine is being written, it may end in RTS. Two of the examples in this article end in other ways. However, these words are never executed within Forth, as their return statements would cause the ATARI to lock up. Selection of the appropriate re-entry point will depend on your requirements for the stack; these points are fully described in the assembler documentation.
The definition of INSTALL is a good example of a traditional Forth assembler word. Note that INSTALL begins with CODE instead of ':' and ends with a C; instead of ';'. These are defining words which switch in the ASSEMBLER vocabulary while the definition is being compiled. The word INSTALL is designed to synchronously set the deferred vertical blank vector; this prevents the vertical blank routine from occurring while the new vector is being set up. INSTALL can also be used to set vectors for system timers 1-S and the immediate vertical blank by changing the #7 in line 10 of screen 11 as follows:
Vector | Value |
---|---|
Timer 1-5 | # 1-5 |
Imm. VBLANK | # 6 |
Screen 12 contains the world VBLANK, which turns the routine on and off, and uses INSTALL to insert the address in the appropriate subroutine. Screen 13 contains the vertical blank subroutine, a simple word which increments the background color in any graphics mode. TEST is the word which brings it all together, installing the address and diverting the vertical blank flow through the subroutine ROTBAK. Note that ROTBAK ends with JVB JMP,. JVB is the re-entry point for the vertical blank routine and is defined as a constant on screen 11. All vertical blank routines must end this way.
To use, LOAD screens 10-13 and type TEST. The background color should begin to change. To turn off this routine, type OFF VBLANK. It is important to remember to turn off vertical blank routines before doing anything to the Forth dictionary. If you FORGET all or part of your routine, the vertical blank vector will be pointing at nothing, and the machine will lock up.
GR7DLI increments the variable COUNTR each time the subroutine is called. Since there are 79 interrupts in our modified display list, COUNTR is reset to zero after 79 (hex 4F) executions. COUNTR is used in the X register as an index into COLTAB (color table) which is really page 2. The color selection in this example is therefore random, but COLTAB could easily point to a user-defined color table. GR7DLI is the Forth translation of the routine which appears on pages 5-6 of De Re Atari, which also contains an excellent discussion of display list interrupts and their application. Note that the subroutine GR7DLI ends with RTI, since it will be called as an interrupt by the operating system. 80COLORS is optimistically named, since many of the colors from our page two color table are black, but it does produce an interesting display when executed. Note that screen 22 uses SUBROUTINE, so screen 10 must be loaded first.
Accompanying this example is a listing of GR7DLI (Listing 2) written with the Atari Assembler Editor. Check this listing with screen 22 to see how the Forth assembler compares. It may be easier to learn the "backward" assembler using this as a basis for comparison.
The Forth assembler can be used to code critical routines for speed, and it can be used for machine language routines such as those described above. For further study in this area, I recommend ValFORTH's 6SO2 Macro Assembler, and De Re Atari, available from APX.