                   Mixing C and Assembly Language
                   ______________________________



       The MIX utility (MIX.COM) translates a Microsoft object (.REL)
       file to a MIX object (.MIX) file.  The MIX utility allows you to
       link assembly language routines (written using the Microsoft M80
       assembler) to your MIX C programs.  After an assembly language
       source file has been assembled by M80, the MIX utility must be
       used before linking the assembly language object code with the
       MIX LINKER.  As an example, assume that you have an assembly
       language source file named TEST.MAC.  You would then assemble
       TEST.MAC using M80.  This would produce an object file named
       TEST.REL.  Then type MIX TEST to translate the TEST.REL file to
       a TEST.MIX file.  The TEST.MIX file can then be linked using the
       MIX LINKER.

       The assembly language macros in the file named MIXMAC.MAC make
       it easy to write assembly language routines that are callable as
       C functions.  This file must be included at the very beginning
       of your assembly language source file (eg.  INCLUDE MIXMAC.MAC).

       The MIXMAC.MAC file defines 6 macros: MODBEG, PROCBEG, GETARG,
       CALLC, PROCEND, and MODEND.  The MODBEG macro defines an
       arbitrary name to associate with the assembly language source
       file.  The PROCBEG macro defines the beginning of a function and
       optionally places arguments passed to it in specified registers.
       The GETARG macro is an alternate method for retrieving function
       arguments.  The CALLC macro is used to call functions that are
       written in C.  The PROCEND macro defines the end of a function
       and optionally returns a value.

       In the following macro descriptions, optional parameters are
       enclosed by the {} symbols.

       1) MODBEG module_name

         The MODBEG macro must be placed at the beginning of an
         assembly language source file (after the INCLUDE MIXMAC.MAC
         statement).  Module_name is an arbitrary name that is
         associated with the function(s) in the assembly language
         source file.  For example you might use MODBEG GRAPHICS to
         name a set of functions that perform graphics operations.
         The MIX LINKER displays the module_name on the screen when
         the assembled function(s) are loaded.

       2) PROCBEG func_name{,arg1},{,arg2}{,arg3}...{,arg8}

         The PROCBEG macro begins a function definition.  Func_name
         defines the name of the function.  Only the first six
         characters of the function name are significant.  Arg1
         through arg8 are optional arguments.  The arguments can be
         any of these Z80 registers: A, BC, DE, HL, A$, BC$, DE$, HL$
         where the $ symbol represents the alternate register set.
         From 0 to 8 of these registers can be specified in any order
         to hold values passed to the function.  For example, PROCBEG
         STRLEN,BC could be used to define a function named STRLEN
         that has one integer argument (perhaps a pointer to a string
         of characters).  The integer argument is placed in the BC
         register.  All arguments are considered to be 16 bit
         integers.  Passing a long (32 bit) integer to an assembly
         language function would require two 16 bit arguments.  As an
         example, PROCBEG GETREC,BC,DE could be used to define a
         function named GETREC with a long integer argument.  The BC
         register would contain the upper 16 bits and the DE register
         would contain the lower 16 bits of the long integer.  Note
         that when A or A$ is used as an argument, the lower byte of
         the two byte argument value is placed in the A register.  This
         makes A or A$ useful only for storing argument values that are
         greater than or equal to 0 and less than or equal to 255. The
         following table lists the sizes (in bytes) of the various C
         data types.  Remember that the char data type is converted
         to int and the float data type is converted to double
         automatically in C expressions.

         C data type              size (in bytes)
         in calling function      at entry to assembly language function
         -------------------      --------------------------------------

              char                              2
              short                             2
              int                               2
              unsigned                          2
              long                              4
              float                             8
              double                            8

         The code for your assembly language function follows the
         PROCBEG macro.  At entry, the IX register points to the base
         of any arguments passed to the function.  The arguments are
         accessed as negative offsets from IX.  The upper byte of the
         first argument is located at address (IX-1).  The IX
         register must be preserved. The IY register points to the
         process record.  The IY register must also be preserved.
 
         Your assembly language function can use any of the Z80
         registers as long as these rules are followed:

         1. IX must be preserved
         2. IY must be preserved
         3. SP must be restored (if it has been altered) before
            using the PROCEND macro to terminate the function

       3) GETARG number,reg

         The GETARG macro may be used to retrieve any of the
         arguments passed to a function.  The GETARG macro assumes
         that the IX register points to the base of the arguments.
         Number specifies the argument number (eg.  1 for first
         argument, 2 for second, etc.).  Reg specifies any of the Z80
         registers described for the PROCBEG macro above.  The macro
         moves the argument into the specified register.  The GETARG
         macro also assumes that all arguments are integers.  You
         must compensate for this assumption when the arguments are
         longs or doubles.  For example assume that a function has
         two arguments, the first a long integer and the second an
         integer.  Then the statement GETARG 1,BC places the upper
         word of the long integer argument into BC.  The statement
         GETARG 2,DE places the lower word of the long integer
         argument into DE.  The statement GETARG 3,HL places the
         integer argument into HL.  Notice that the long integer
         (since it is 4 bytes instead of 2) is accessed as argument 1
         and 2.  The second integer argument is therefore accessed as
         argument number 3.  Note that when A or A$ is specified for
         reg, the lower byte of the two byte argument value is placed
         in the A register.  Therefore A and A$ are useful only when
         the value passed is greater than or equal to 0 and less than
         or equal to 255.

       4) CALLC func_name{,arg1}{,arg2}{,arg3}...{,arg8}

         The CALLC macro is used to call C functions.  Func_name
         specifies the name of the C function.  Arg1 through arg8 are
         the optional arguments that are passed to the C function.
         Any of the Z80 registers described for the PROCBEG macro
         above may be used as arguments.  For example, CALLC PERROR,BC
         calls the standard perror function and passes it the integer
         (or pointer) value contained in BC.  When the C function
         terminates, a return value will be on top of the stack.  It
         is your responsibility to pop the return value off the stack.
         Since not all C functions return integer values, you must be
         careful and pop the correct number of bytes from the top of
         the stack.  For example, two pop instructions are required if
         the C function returns a long integer or a float.  If the C
         function is defined as type void there is no return value on
         top of the stack.  The IX and IY registers are preserved when
         a C function is called.  All other registers will have
         different values when the C function returns control to the
         assembly language function.

         The supplied object file named CALLC.MIX must be linked to
         your program if the CALLC macro is used.  The object code
         from this file is also contained in the file named
         ASMLIB.MIX which is described below.
  
       5) PROCEND func_name{,ret1}{,ret2 }{,ret3}{,ret4}

         The PROCEND macro ends a function definition.  Func_name
         defines the name of the function.  The function name must be
         the same name as used in the previous PROCBEG macro.  Ret1
         through ret4 are optional Z80 registers that contain the
         function return value.  From 0 to 4 of the Z80 registers: A,
         BC, DE, HL, A$, or HL$ can be specified in any order.  For
         example, PROCEND STRLEN,HL could be used to return the
         integer value contained in the HL register.  PROCEND
         GETREC,BC,DE could be used to return the long integer value
         contained in the BC and DE registers (BC containing the
         upper word and DE the lower word).  If no registers are
         specified following the function name, then no value is
         returned.  In this case the C function that calls it must
         declare the assembly language function as an external
         function of type void.

       6) MODEND module_name

         The MODEND macro must be placed at the end of an assembly
         language source file.  Module_name must be the same name as
         used in the MODBEG macro at the beginning of the source
         file.

       The following represents the general structure of a library of
       assembly language functions.

            INCLUDE MIXMAC.MAC    ;include macro definitions

            MODBEG asmlib         ;define name for library

            PROCBEG func1
               .
               .                  ;definition of function 1
               .
            PROCEND func1

            PROCBEG func2
               .
               .                  ;definition of function 2
               .
            PROCEND func2
               .
               .
               .

            PROCBEG funcn
               .
               .                  ;definition of function n
               .
            PROCEND funcn

            MODEND asmlib         ;end of library
            END
   

       The file named SAMPLE.MAC contains several assembly language
       functions that are called from the C program in the file named
       SAMPTEST.C.  The file named BUILD.SUB is a batch file that
       compiles the SAMPTEST.C program, assembles the SAMPLE.MAC file,
       converts the resulting SAMPLE.REL file to a SAMPLE.MIX file, and
       then builds a .COM file named SAMPTEST.COM.  The BUILD.SUB file
       assumes that M80.COM, SUBMIT.COM, CC.COM, CC.OVY, LINKER.COM,
       and RUNTIME.OVY are all on drive A.  Make sure the selected
       drive is the one containing this disk and then simply type
       A:SUBMIT BUILD to execute the batch file.

       The MIX utility is executed using the following syntax.

                   MIX <OBJ file> <MIX file>

       Examples:

       1. MIX file              ;translates file.rel to file.mix
       2. MIX file1 file2       ;translates file1.rel to file2.mix
       3. MIX file.ctl          ;translates one or more object files
                                 listed in file.ctl to file.mix

       File name extensions are optional.  If no extensions are
       specified, .REL is used for the first parameter and .MIX is used
       for the second.  The second parameter is optional.  If it is
       omitted the .MIX file is given the same name as the first
       parameter but with an MIX extension.  Multiple .REL files can be
       translated to a single .MIX file through the use of a control
       file.  Use of a control file is signaled to the MIX utility when
       the first parameter contains a .CTL extension.  The .CTL file
       must contain a list of object file names with one file name per
       line.  The MIX utility will then create a single .MIX file
       containing all the REL files listed in the .CTL file.  When
       multiple assembly language functions are assembled together in
       the same source file (as with SAMPLE.MAC), the functions are not
       separable.  This means that when the functions are linked to a C
       program, all the functions become a part of the program even if
       some of them are not used.  To create a library of functions
       that are separable you must assemble each function separately.
       This creates a separate .REL file for each of the assembly
       language functions.  The MIX utility (MIX.COM) can then combine
       the multiple .REL files into a single .MIX file.

       There are several files on this disk with .MAC extensions.
       These are assembly language source files containing one function
       per file.  Each MAC file also contains a brief description of
       the function.  The file named ASMLIB.MIX contains the object
       code for all of these functions.

       There are two batch files on the disk that were used to create
       the LINKER.MIX file.  These batch files provide an example of
       how to merge separately assembled assembly language functions
       into a single searchable .MIX file.  The ASSEMBLE.SUB file is
       first used to assemble all the assembly language functions.
       Then the MERGE.SUB file is used to merge all the object files
       into a single .MIX file.  The MERGE.CTL file provides the list
       of assembly language files that are input to the MIX utility.
       With the selected disk containing this disk and the M80.COM and
       SUBMIT.COM files on drive A, simply type A:SUBMIT ASSEMBLE
       to assemble all the MAC files and then type A:SUBMIT MERGE to
       create the ASMLIB.MIX file.

       The M80 assembler puts out a maximum of 6 characters for
       function names.  Because some of the functions in the library
       have names longer than 6 characters, the ASMLIB.MIX file must
       be modified.  Use the CONVERT.COM program supplied with MIX C
       to convert the ASMLIB.MIX file to ASCII (eg. A:CONVERT ASMLIB).
       Now you can edit the ASMLIB.MIX file and add the missing
       characters to the function names that are longer than 6
       characters.  The functions in the ASMLIB.MIX file are easily
       distinguished.  Each function starts with a J tag which is
       immediately followed by the function name.  The function name
       also appears in 2 other places following G and I tags.
       All 3 names must be changed.  Each name occupies 8 characters
       and is blank filled on the right if the name contains less than
       8 characters.  When you modify a function name, make sure that
       it fits in the 8 character field.  The following function
       names must be changed in the ASMLIB.MIX file.  If you are using
       the MIX Editor, the RG command should be used to replace the
       strings (eg. RG "ISGRAP  " "ISGRAPH ").

            Function Name               Change To
            -------------               ---------

              "ISGRAP  "                 "ISGRAPH "
              "ISXDIG  "                 "ISXDIGIT"
              "STRRCH  "                 "STRRCHR "
              "STRCSP  "                 "STRCSPN "
              "STRPBR  "                 "STRPBRK "

       Once the above function names have been changed, save the
       file and use the CONVERT.COM program to convert ASMLIB.MIX
       back to binary format (eg. A:CONVERT ASMLIB).

       The LIBTEST.C file contains the C program that was used to test
       the assembly language functions. You can execute this program by
       typing A:CC LIBTEST to compile the program.  Then type
       A:LINKER LIBTEST,ASMLIB to link the program.  The program can then
       be executed by typing LIBTEST.  Using this method to link a library
       loads all the functions in the library.  If your program only
       uses a few of the functions you will want to search ASMLIB.MIX
       rather than load it.  This requires that you use the long form
       of the linker.  For example:

       A:LINKER
       >>L LIBTEST
       >>F ASMLIB,CLIB
       >>B
       STACK SIZE : 5K
       Include runtime support in command file? Y
       FILE     = LIBTEST.COM
hen
       be executed by typing LIBTEST.  Using this method to link a library
       loads all