I had always thought of inverse video as something other computers could do and my TI-99/4A could not. When I obtained TI's MICROSOFT MULTIPLAN and saw that program's use of inverse video I realized the obvious: while TI's built in video firmware cannot provide an inverse image, software can be written to do the trick. TI-FORTH makes the trick easy.

One approach to writing an inverse video routine makes use of an internal memory map which leaves all 256 ASCII characters available for definition and display. This is the approach taken by MULTIPLAN, and there is plenty of room in that configuration to define a whole alternate set of inverted characters between characters 128 and 256. Since the VDP processor thinks of the screen image as a long array of single byte values, it is an easy trick to just find the values which define the section of the screen you want to invert, and then add the 128 offset to each byte to obtain the inverted characters.

Unfortunately there are several drawbacks to that approach. First you have to store the 95 inverted character definitions in your TI-FORTH routine, and that'a a lot of wasted space. Second, you have very few characters available for graphics, if you want them. Finally, it is extremely inelegant.

A relatively compact and much more elegant solution can be written in TI-FORTH, however, and I have found it so valuable that I have added it to my personalized 'BSAVEd' kernal, so I can have it available for all my applications as I write them.

Here's an outline of the task:

  1. Define screen segment to be inverted by position and length.
  2. Read the defined segment of the screen image byte array into a character buffer.
  3. Read the 8-byte character definitions of each character to be inverted into a pattern buffer.
  4. Invert the pattern buffer.
  5. Write the inverted patterns consecutively into VDP memory to redefine a predetermined set of unused ASCII characters.
  6. Write an appropriate sized section of redefined characters into the screen image array at the correct location.

By use of variables to hold the screen location and the segment length, and use of a character buffer to hold the original screen segment, reversal of the inversion is simple: re-write the character buffer to the saved screen location.

The pseudo-code program presented above is easlily implemted in TI-FORTH. The version presented here is actually a direct conversion from TMS 9900 Assembly Language. The set of "system synonyms" provided in TI-FORTH makes it possible to translate many machine language tasks without use of the separate (and somewhat cumbersome) ASSEMBLY and CODE vocabularies. All kinds of VDP memory manipulation are possible, and since this program is almost entirely VDP manipulation, all you need to do is make sure the -SYNONYMS screen is loaded before you load the screens listed here.

The program listing is largely self-documenting and straightforward. Enter a row number, a column number and a segment length on the stack and the word INVERT, and you get inverse video. REVERT restores the original characters. INVERTS uses the same primitives to flash your inversion, and requires the addition of the number of flashes on the stack. Use of the User Variable SCRN_WIDTH to convert row and column to screen location means the procedure will work in GRAPHICS or TEXT modes. It will not work in bit-mapped or multi-color modes, obviously.

Notice that extremely deep stack manipulations are avoided by the simple expedient of using the LOC and LEN variables, and the word VARS to set those variables once from the initial stack. The information could be passed in the stack, but that would make for a much less elegant solution, and a listing a lot less easy to read. The definitions as presented provide no error checking, and allow for a maximum segment of 40 characters. Enter inappropriate values on the stack at your own risk! The original machine language version was meant to link with TI's Extended BASIC and could only use characters 128 through 143. The longer segment lengths in TI-FORTH are achieved at the cost of increased memory size for the buffers. One could easily modify the buffers and maximum segment length to conserve memory.

Richard Minutillo
74 Hawthorne Street
Roslindale MA 02131
May 20, 1985