!lm12
!rm75
The Macro-Videx Connection........................Don Taylor

It seems that whenever I purchase a new hardware product for my Apple, I spend countless hours honing my most precious software tools to make them compatible with it.  I purchased my Videx Videoterm card for use with Pascal, and had no intention of using it with the S-C Assembler.  Then one fateful day I made a temporary patch to Version 4.0 -- just to see what it would look like -- and I was immediately hooked....

You won't believe what it's like to assemble with 80 columns of display!  You can actually write source files that are legible on the screen, with no wraparound on comments -- even during assembly.  What you see on the display is what you would see on a printer, only cleaner.

When I upgraded to the S-C Macro Assembler, I was compelled to produce a configuration file that would modify the new assembler to work with the Videoterm board.  The resulting source file is included with this article.

The assembled SCM80 file will reconfigure a copy of the S-C Macro Assembler Version 1.0 that is currently resident in memory (for more about this concept, see "Controlling Software Configuration",  AAL April '82).

Once the mods are installed you will be able to use your Videx for everything except:  (1) Using the Escape-L sequence to LOAD a disk file whose name appears on the display, and (2) Using the copy key (right arrow).  You will still be able to use Escape-L to generate the normal dashed comment line, and you can use the other escape functions to move the cursor and clear portions of the screen.

SCM80 will display control characters (and other selected strings intended to be so) in inverse on your screen, provided you have the standard (inverse) alternate character generator ROM installed in your Videoterm.  If you have some other ROM installed, these characters and strings may be printed in Chinese.  In this case you may want to modify the new character output routine!

SCM80 will also permit painless switching of case while using the assembler.  A control-A keypress will always be recognized as a "shift lock" signal, while a control-Z will be treated as a "shift unlock".  This feature makes it easy to write easy-to-read source files.

The assembled SCM80 code is moved into memory immediately following the assembler, and is located at one of two places, depending on which flavor (vanilla or language card) of the assembler you're using.  The flavor of the configuration file is made to match that of the assembler through the use of a conditional flag (LCVERSION) and several conditional assembly statements.  Another equate variable, SLOTNUM, allows you to specify the slot in which your Videx board resides.
!np
How It All Works

There are two primary steps involved in installing the modified code in the assembler:  (1) Moving the new code into the area of memory immediately following the assembler, and (2) Patching the existing assembler code to point to the new routines and then returning or cold-starting the system.

The SCM80 code contains both the new Videoterm support routines and the routines used to install those support routines.  It loads in at $4000, stuffs the Videoterm routines just beyond the assembler code, and then performs the return or cold start.  Depending on the flavor, a few other small tasks are performed in the process; let's take a closer look.

Lines 1280-1310 contain the two constants used to tailor SCM80 to assembler flavor and Videoterm slot number.  The last two lines are the starting addresses where the new code will be relocated, depending on the flavor.  The LCVERSION flag is used to determine the base address of the assembler in lines 1340-1380; this base address is used throughout the rest of the listing to determine absolute patch addresses within the assembler.

The Videoterm support routines are contained in lines 3240-3770.  Lines 3400-3700 contain replacement routines for two of the routines in the line editor portion of the assembler.  The NEW.WARM.ENTRY routine in lines 3240-3260 is intended to keep the Videoterm in the saddle during a RESET or system warm start.

The code in lines 3820-4740 are replacements for some of the standard monitor routines.  Several of these routines have no other purpose than to support the escape cursor movements.  In the case of the language card flavored RDKEY, an extra subroutine is provided to unprotect the RAM during case-shift sequences (more about that in a minute).

Lines 1770-2040 use the monitor's MOVE routine to slip the support routines into their designated origin at $3200 or $F400.  The vanilla version patches the assembler's symbol table address to make room for the move; the language card version unprotects RAM prior to the move.

The patching of the assembler is done in lines 2050-2920.  unused code is NOP-ed out here, and jumps are strategically poked in to point to the new routines.  A replacement escape jump table created in lines 2950-3090 gets installed in the assembler, so the new escape routines can be accessed in the standard manner.  The assembler's cold start routines are patched to point to the resilient NEW.WARM.ENTRY routine (more about that in a monent, too).

Lines 2870-2920 complete the installation and patching process.  For the vanilla version, a simple RTS returns control to the calling program.  The language card version first write protects RAM and then performs a DOS cold start.  Once the assembled code has been installed and the patches made, the installation portion of SCM80 is of no use, so a cold start should be performed to reset the assembler's file pointers, leaving only the SCM80 code that is now supporting your Videoterm.


Assembly and Installation

You'll note the absence of any .TF directive in the listing, meaning you'll have to manually save this file when you're done.  This is because although the resulting object code will be located in continuous memory, it has origins (.OR directives) at two locations.  The actual length of the file is calculated by a variable called LENGTH.  The instructions for assembly are contained in the source file's title block.  I call my vanilla patch file SCM80, and the language card version SCM80.LC.

With the assembler code resident in memory, there are several ways of installing the patches.  Perhaps the most straightforward is to BRUN the assembled patch file, or BLOAD it and type 4000G as a monitor command.  If you're using the vanilla assembler, you'll need to force a cold start of the assembler by typing "NEW" or 1000G as a monitor command; this action will ensure all the internal patches have been installed into DOS as well.  The language card version cold starts itself, and requires no intervention.

A cleaner way is to use an EXEC file.  The following file will bring up the vanilla version of the assembler:

!lm+5
REM LOAD ASM
CALL -151                Enter the monitor
BLOAD S-C.ASM.MACRO      Load the Assembler
BLOAD SCM80              Load the patches
4000G                    Install them, and
1000G                    Start the assembler!
!lm-5

To load the language card patches with an EXEC file, refer to Bob's EXEC file on the top of Page 4 of the May '82 AAL, and replace "3D3G" with the following two lines:

!lm+5
BLOAD SCM80.LC           Load the LC patches
4000G                    Install them and cold start!
!lm-5

The character I/O is being vectored through routines at the end of the assembler; for the language card version, these routines are somewhere in $F4XX.  If you decide to issue an "FP" command from that version, you'll find yourself in "Never-Never Land".  It's good practice to issue a "PR#n" first (where "n" is the Videoterm's slot number).  When you type "INT" to restart the assembler, the special I/O routines will automatically be hooked in.
!np
A Funny Thing Happened on the Way...

Bob thought it would be enlightening to touch on some some of the crazy things that went on during the development of these routines.  I always marvel at people like Bob, Mike, Bill, and Lee, who have a gift for writing machine language, and can sit down and bang out a line editor in a few hours.

The rest of us aren't quite so fortunate.  SCM80 took my three days to write, even though I had done some quick patches on Version 4.0.  A couple of good ones popped up during that time, and I'll pass them along.

I was determined to interface the Videoterm using only its terminal functions, avoiding any internal Videoterm ROM routines that would make the interface version-dependent (my card matches neither the descriptions nor the ROM  source listings contained in my manual!).

The Videoterm will not move its flashing cursor to a GOTOXY Location unless the cursor is first placed there and then a character is output; under BASIC, you can't just HTAB and VTAB to a position and GET a character -- you have to print a character first (even a null character will do it), in order to move the cursor!

After spending several hours fighting with the Videoterm over who was controlling the input and output cursor locations, I finally decided to designate my own locations for CH and CV (normally at $24 and $25) for use by the editing routines.

The other frustration I incurred was doing the case-switching in the replacement RDKEY routine.  I was using the language card version, and had carefully checked my code, but the assembler just wouldn't switch case for me.  True confession: it took almost fifteen minutes before it dawned on me that the assembler's case flag (at $D016) was write protected!  Hence, the special unprotect subroutine called by the new RDKEY.                

One final note concerns the contortions in the replacement COUT and WARM.ENTRY routines (at least I saw these coming!).  We need to keep our new RDKEY routine in the DOS input hook to keep things working predictably.  The Videoterm, when installed by placing it in the output hook and calling it to output a character, takes over the input hook as well.  In addition, we have a replacement COUT routine that is designed to detect and modify control characters for display prior to their output.

In order to avoid arm-wrestling with the Videoterm over who controls the input hook, I used a strange but effective technique.  During the installation and patch portion, I install the Videoterm in the designated slot, hook it in, and send a bogus character to make sure it has installed its warm entry I/O locations in DOS ( $AA52-$AA56 for 48K machines).  The code immediately following uses an internal assembler routine to calculate the address of the DOS output hook, regardless of memory size.  The contents of the DOS output hook are then moved into the new COUT routine, immediately following a JMP, and the same COUT routine is forced into the DOS hook, along with the new RDKEY routine.  Whenever a character is output, it will first be given to COUT; when COUT has done its work, the character is then passed to the Videoterm's warm entry.

During the installation and patch, the warm start vector within the assembler was modified to point to the NEW.WARM.START routine, which re-installs COUT and RDKEY, keeping everything in sync.  A RESET will always restore this condition, no matter what the Videoterm may have in mind!

The S-C Macro Assembler is a wonderful piece of software, and the upgrade is a steal at $27.50.  The only thing that can top it is being able to use it with 80 columns of display!

If you find any errors in my patches, or come up with some new features, contact me at (206) 779-9508.
