home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / XLIB40.ZIP / EASYX.DOC < prev    next >
Text File  |  1994-03-25  |  26KB  |  783 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.                             EASYX PROGRAMMER'S MANUAL
  30.                                    VERSION 1.2
  31.  
  32.                               (DOS Extender Library)
  33.  
  34.                                 TechniLib Company
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.                   Copyright 1993 1994, by TechniLib (TM) Company
  61.                                All Rights Reserved
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.                           TERMS OF USE AND DISTRIBUTION
  69.  
  70.  
  71.        XLIB is a shareware product; therefore, unregistered copies of XLIB are
  72.   made available free of charge so that potential purchasers will have the
  73.   opportunity to examine and test the software before committing payment.
  74.   Distribution of unregistered copies of XLIB to other potential users is also
  75.   permitted and appreciated.  However, usage and distribution of XLIB must
  76.   conform to the following conditions.  In the following statement, the term
  77.   "commercial distribution," includes shareware distribution.
  78.  
  79.   1) XLIB and accompanying software must be distributed together in copies of
  80.   the original archive provided by TechniLib.  Neither the archive nor
  81.   individual files therein may be modified.
  82.  
  83.   2) The XLIB archive may be distributed in combination with other shareware
  84.   products; however, the XLIB archive may not be distributed with other
  85.   commercially distributed software without written consent of TechniLib.
  86.  
  87.   3) Copies of XLIB which have been used to develop software for commercial
  88.   distribution must be registered before such software is marketed.  Copies of
  89.   XLIB which have been used to develop noncommercial software must be registered
  90.   if such software is to be regularly used either by the developer or others.
  91.  
  92.   4) Commercially distributed software must embed XLIB procedures in the
  93.   software code.  Files contained in the XLIB archive may not be placed in the
  94.   distribution media.
  95.  
  96.   5) XLIB is designed to offer a set of services to other executable code.  XLIB
  97.   may not be used to develop software for commercial distribution which will
  98.   essentially offer any of these same services to other executable code.
  99.   Exceptions to this condition require written consent of TechniLib.
  100.  
  101.   6) Rights afforded by registering a single copy of XLIB pertain only to a
  102.   single computer.
  103.  
  104.   7) XLIB may be registered for a fee of $40.00 per copy.  Accompany payment
  105.   with the registration form included in the XLIB archive.  Registrants will be
  106.   entitled to the most recent version of the XLIB archive.
  107.  
  108.  
  109.                               DISCLAIMER OF WARRANTY
  110.  
  111.  
  112.        XLIB AND ALL ACCOMPANYING SOFTWARE AND LITERATURE ARE DISTRIBUTED WITH
  113.   THE EXCLUSION OF ANY AND ALL IMPLIED WARRANTIES, AND WITH THE EXCLUSION OF
  114.   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  TechniLib
  115.   SHALL HAVE NO LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  116.   RESULTING FROM THE USE OF XLIB OR ACCOMPANYING MATERIALS.  The user assumes
  117.   the entire risk of using this software.
  118.  
  119.  
  120.                   Copyright 1993 1994, by TechniLib (TM) Company
  121.                                All Rights Reserved
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.                                 TABLE OF CONTENTS
  129.  
  130.  
  131.   CHAPTERS
  132.                                                                       Page
  133.   1. Introduction                                                        1
  134.   2. Initialization of EASYX                                             2
  135.   3. Memory Management                                                   3
  136.   4. Memory-Mapped Input/Output                                          5
  137.   5. File Management                                                     6
  138.  
  139.  
  140.   EXAMPLES
  141.                                                                       Page
  142.   1.  EASYX Memory Management                                            4
  143.   2.  EASYX File Management                                              9
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.                                  1. Introduction
  151.  
  152.  
  153.        EASYX is a DOS extender library intended for programmers who are
  154.   unfamiliar with assembly language.  EASYX allows real-mode high-level
  155.   languages to perform transfers between extended memory and conventional memory
  156.   or between extended memory and disk files.  Many programmers need a DOS
  157.   extender merely to afford real-mode languages access to extended memory.  In
  158.   such cases, EASYX is a simple and powerful alternative.
  159.        EASYX is actually little more than a real-mode interface to XLIB.  The
  160.   source code for EASYX is supplied in the XLIB archive (EASYX.ASM).  Assembly
  161.   language programmers may be interested in examining this code to learn more
  162.   about working with XLIB.  This code has been assembled and then linked with
  163.   XLIB.LIB to create EASYX.LIB.
  164.        The EASYX library is provided in two formats - one for Microsoft
  165.   languages and the other for Borland languages.  Microsoft programmers should
  166.   use EASYX.LIB.  Borland programmers should use EASYXB.LIB.  The respective C
  167.   header files are EASYX.H and EASYXB.H.  Programmers using other languages will
  168.   have to write their own prototypes for EASYX procedures.  These prototypes
  169.   should declare all EASYX procedures as far procedures conforming to the PASCAL
  170.   calling and naming convention.  Prototypes for Microsoft BASIC 7.0 are
  171.   presented in the files EASYXEX1.BAS and EASYXEX2.BAS.
  172.        The programmer might prefer to use EASYXE.LIB rather than EASYX.LIB.  The
  173.   former has CPU exception trapping capabilities whereas the latter does not.
  174.   EASYXE.LIB will always trap exceptions occurring in protected mode.  It can
  175.   also trap real-mode exceptions provided that a DPMI 1.0 host is installed.
  176.   Borland programmers should use EASYXEB.LIB.  C and C++ programmers should
  177.   continue to use EASYX.H or EASYXB.H for header files.
  178.        Most EASYX procedures can return error codes.  These are always XLIB
  179.   error codes.  The codes are explained in the XLIB documentation.
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.                                         1
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.                             2. Initialization of EASYX
  215.  
  216.  
  217.        EASYX requires no initialization; however, the XLIB library which has
  218.   been linked with EASYX must be initialized before any EASYX procedures are
  219.   called.  XLIB is initialized by calling INITXLIB.  INITXLIB returns an error
  220.   code in DX:AX; therefore, it should be implemented as a long integer function.
  221.   The following code demonstrates initialization in Microsoft C:
  222.  
  223.  
  224.   extern long __far __pascal INITXLIB(void);
  225.  
  226.   void main(void)
  227.   {
  228.     long errcode;
  229.     errcode = INITXLIB();
  230.     if(errcode != 0)
  231.     {
  232.       printf("Initialization error:  %lX",errcode);
  233.       return;
  234.     }
  235.   .
  236.   .
  237.   .
  238.  
  239.        An explanation of possible error codes is explained in the XLIB
  240.   documentation.  The most common error is caused by insufficient conventional
  241.   memory.  INITXLIB will attempt to allocate a small amount of conventional
  242.   memory through DOS; however, many high-level languages automatically claim all
  243.   available DOS memory, even though only a small percentage of this memory may
  244.   actually be used.  The programmer must therefore release a portion of this
  245.   memory back to DOS before calling INITXLIB.  This process is illustrated for
  246.   the Borland Turbo Assembler in the file EXAMP1B.ASM, and for Microsoft BASIC
  247.   in EASYXEX1.BAS.  C and C++ programmers need not be concerned with this matter
  248.   because these languages allocate DOS memory dynamically.
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.                                         2
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.                                3. Memory Management
  279.  
  280.  
  281.        High-level languages confined to real mode are incapable of addressing
  282.   extended memory; consequently, such languages must communicate with extended
  283.   memory through buffers in conventional memory.  EASYX provides several
  284.   procedures to facilitate this process.
  285.        Extended memory should always be allocated with the procedure XMALLOC
  286.   before it is addressed.  Attempted transfers to or from unallocated memory may
  287.   lead to page faults (exception 14), or to corruption of resident software.
  288.   XMALLOC returns a long integer error code; therefore, it should be implemented
  289.   as a long integer function.  The following Microsoft C prototype shows the
  290.   structure of XMALLOC:
  291.  
  292.  
  293.   extern long __far __pascal XMALLOC(long nobytes, long __far *address,
  294.      long __far *size, long __far *handle);
  295.  
  296.   where:
  297.   nobytes  = The requested size for the extended memory block.
  298.   *address = A far pointer to a long integer variable which will receive the
  299.              linear address of the allocated block.
  300.   *size    = A far pointer to a long integer variable which will receive the
  301.              actual size of the allocated extended memory block.  The actual
  302.              size will always be at least as large as the requested size.
  303.   *handle  = A far pointer to a long integer variable which will receive a
  304.              handle for the allocated extended memory block.  The handle must
  305.              be used to release the block.
  306.  
  307.  
  308.        An extended memory block can be released with the XFREE procedure.  XFREE
  309.   is also a long integer function which returns an error code.  The C prototype
  310.   of this procedure is:
  311.  
  312.  
  313.   extern long __far __pascal XFREE(long handle);
  314.  
  315.   where:  handle = The handle assigned to the block by XMALLOC.
  316.  
  317.  
  318.        All extended memory is automatically released upon program termination;
  319.   consequently, XFREE will not be necessary for most programs.
  320.        Transfers between conventional memory and extended memory can be
  321.   accomplished with the MOVMEM procedure.  The prototype for MOVMEM is:
  322.  
  323.  
  324.   extern void __far __pascal MOVMEM(long destadr, long sourceadr,long nobytes);
  325.  
  326.   where:
  327.   destadr   = The linear address of the destination memory.
  328.   sourceadr = The linear address of the source memory.
  329.   nobytes   = The number of bytes to be transferred.
  330.  
  331.  
  332.  
  333.  
  334.  
  335.                                         3
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.        MOVMEM may actually be used to transfer memory between any source and
  343.   destination.  The destination block and source block may also be overlapped.
  344.        MOVMEM transfers are faster than XMS or INT 15H because MOVMEM uses 32-
  345.   bit instructions.  MOVMEM also exposes to less risk of losing an interrupt.
  346.        MOVMEM is a reentrant procedure, so it may be safely called within
  347.   interrupt handlers.  When MOVMEM is being used in a hardware interrupt
  348.   handler, the handler should be installed after the call to INITXLIB to prevent
  349.   a call to MOVMEM before protected-mode structures have been initialized.
  350.        Real-mode programs use segment addresses instead of linear addresses.
  351.   EASYX includes a procedure called LINADR which computes linear addresses from
  352.   segment addresses.  The prototype for LINADR is:
  353.  
  354.  
  355.   extern long __far __pascal LINADR(void __far *ptr);
  356.  
  357.  
  358.        The following program uses the procedures presented in this section.  The
  359.   file EASYXEX1.BAS contains a Microsoft BASIC 7.0 version of the program.
  360.  
  361.  
  362.   Example 1:  EASYX Memory Management
  363.   _____________________________________________________________________________
  364.   #include <stdio.h>
  365.   #include <easyx.h>
  366.  
  367.   void main(void)
  368.   {
  369.     long errcode, nobytes, xaddress, xsize, xhandle, bufferaddress;
  370.     long buffer[1024];            /*4k buffer*/
  371.  
  372.     errcode = INITXLIB();         /*Initialize XLIB*/
  373.     if(errcode != 0)
  374.     {
  375.       printf("Library initialization error:  %lX\n",errcode);
  376.       return;
  377.     }
  378.  
  379.     nobytes = 0x10000;            /*Allocate 64k of extended memory*/
  380.     errcode = XMALLOC(nobytes, &xaddress, &xsize, &xhandle);
  381.     if(errcode != 0)
  382.     {
  383.       printf("Memory allocation error:  %lX\n",errcode);
  384.       return;
  385.     }
  386.  
  387.     bufferaddress = LINADR(buffer);          /*Get linear address of buffer*/
  388.     MOVMEM(xaddress, bufferaddress, 4096);   /*Transfer buffer to extended*/
  389.     MOVMEM(bufferaddress, xaddress, 4096);   /*Transfer extended to buffer*/
  390.  
  391.     errcode = XFREE(xhandle);     /*Release the extended memory*/
  392.     if(errcode != 0)
  393.       printf("Memory release error:  %lX\n",errcode);
  394.   }
  395.   _____________________________________________________________________________
  396.  
  397.  
  398.  
  399.                                         4
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.                           4. Memory-Mapped Input/Output
  407.  
  408.  
  409.        On 386 and higher machines, memory reads and writes may undergo address
  410.   translation so that the address which is physically accessed may be different
  411.   from the address specified in the read/write instruction.  The physically
  412.   accessed address is the "physical address."  The address specified by the
  413.   read/write instruction is the "logical address."  Normally programmers need
  414.   not be concerned with the difference; however, this is not the case if the
  415.   program must access an IO device which maps to a fixed physical address.  In
  416.   such cases, the programmer must obtain a logical address which corresponds to
  417.   the physical address of the IO device.  EASYX contains a procedure called
  418.   MAPIOMEM which will map a specified physical address into a logical address
  419.   space.  MAPIOMEM is a long integer function which returns an error code.  The
  420.   prototype for MAPIOMEM is:
  421.  
  422.  
  423.   extern long __far __pascal MAPIOMEM(long physaddress, long size,
  424.      long __far *logaddress);
  425.  
  426.   where:
  427.   physaddress = The beginning physical address for the IO device.
  428.   size        = The size of the physical address block in bytes.
  429.   *logaddress = A far pointer to a long integer which is to receive the assigned
  430.                 logical address.  Access the IO device at this address.
  431.  
  432.  
  433.        MAPIOMEM will sometimes return errors upon attempts to map physical
  434.   addresses in the first megabyte.
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.                                         5
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.                                 5. File Management
  471.  
  472.  
  473.        EASYX includes procedures which can transfer data between extended memory
  474.   and files.  These procedures can load files to extended memory or save
  475.   extended memory to files.  They can read and write files either sequentially
  476.   or randomly.
  477.        All EASYX file management routines will receive and return values in a
  478.   contiguous block of memory called a "file control block" (not to be confused
  479.   with DOS file control blocks).  The file control block must be located in
  480.   conventional memory and must have the following form:
  481.  
  482.  
  483.   Field Name   Field Type        Field Description
  484.   ----------   ----------        -----------------
  485.   CONDCODE     DWORD             Condition code from file operation
  486.   FNAME        BYTE[68]          File path and name (zero terminated string)
  487.   FHANDLE      WORD              File handle assigned by DOS
  488.   FPTRMODE     WORD              File pointer mode
  489.   FPTR         DWORD             File pointer
  490.   BLKADR       DWORD             Memory source/destination address
  491.   BLKSIZE      DWORD             Size of source/destination block in bytes
  492.   BUFADR       DWORD             Buffer address (conventional memory)
  493.   BUFSIZE      WORD              Buffer size in bytes
  494.   CONTROL      WORD              Control word
  495.  
  496.  
  497.        CONDCODE is used to return error codes.  CONDCODE should be situated at
  498.   the starting address of the control block.
  499.        FNAME is a zero-terminated ASCII string defining the file path and name.
  500.   There cannot be more than 68 characters in this string, including the
  501.   termination character.
  502.        BLKADR and BLKSIZE define the source/destination memory block for the
  503.   transfer.  This block may be in either conventional or extended memory.
  504.   BLKADR is a linear address.
  505.        XLIB uses DOS to access the disk.  DOS cannot read or write to extended
  506.   memory; consequently, a conventional memory buffer must be set up for the DOS
  507.   transfers.  File management routines shift to protected mode to perform
  508.   transfers between the buffer and the source/destination memory.  BUFADR and
  509.   BUFSIZE define the conventional memory buffer.  BUFADR is a linear address.
  510.        For fastest transfers, the memory block and the buffer should be DWORD
  511.   aligned and should have sizes equal to an integer multiple of four.
  512.        FPTR and FPTRMODE specify the file pointer setting to be used before
  513.   intrafile transfers to or from the disk.  FPTRMODE specifies how FPTR is to be
  514.   interpreted.  The following values are valid for FPTRMODE:
  515.  
  516.  
  517.   FPTRMODE    FPTR Interpretation
  518.   --------    -------------------
  519.   0           Unsigned offset from the beginning of the file
  520.   1           Signed offset from the current file pointer
  521.   2           Signed offset from the end of the file
  522.   3           FPTR is ignored.  Use current file pointer (sequential mode)
  523.  
  524.  
  525.  
  526.  
  527.                                         6
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.        CONTROL is not used in the present version of EASYX.  All bits in control
  535.   should be set to zero.
  536.        Since these routines perform disk operations, special precautions should
  537.   be taken to ensure that parameters in the file control block are properly
  538.   defined before performing calls.  In particular, one should always make sure
  539.   that the source/destination memory block and the conventional memory buffer
  540.   are properly defined.  A safe rule is to simply set the buffer size to zero
  541.   because this forces EASYX to supply a buffer when opening or creating the
  542.   file.
  543.        EASYX file routines should not be called within interrupt handlers
  544.   because all of these routines use DOS.
  545.        All EASYX file routines receive a single argument; namely, the far
  546.   address of the control block.  Prototypes for the file routines are:
  547.  
  548.  
  549.   extern void __far __pascal XFCREATE(void __far *controlblock);
  550.   extern void __far __pascal XFOPEN(void __far *controlblock);
  551.   extern void __far __pascal XFCLOSE(void __far *controlblock);
  552.   extern void __far __pascal XFLOAD(void __far *controlblock);
  553.   extern void __far __pascal XFSAVE(void __far *controlblock);
  554.   extern void __far __pascal XFREAD(void __far *controlblock);
  555.   extern void __far __pascal XFWRITE(void __far *controlblock);
  556.  
  557.  
  558.        The following is a detailed explanation of each of these procedures:
  559.  
  560.  
  561.   XFCREATE (Create File)
  562.   Purpose:  Create and open a new file of specified name in specified directory.
  563.   Control Block at Call:  FNAME = file path and name.
  564.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  565.   FHANDLE = file handle assigned by DOS.  If the procedure is called with
  566.   BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
  567.   buffer.
  568.   Details:
  569.      If the file already exists, then it will be truncated to zero length.
  570.      Files created by this routine will be given both read and write access.
  571.  
  572.   XFOPEN (Open File)
  573.   Purpose:  Open existing file of specified name in specified directory.
  574.   Control Block at Call:  FNAME = file path and name.
  575.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  576.   FHANDLE = file handle assigned by DOS.  If the procedure is called with
  577.   BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
  578.   buffer.
  579.   Details:  The file is opened for both read and write access.
  580.  
  581.   XFCLOSE (Close File)
  582.   Purpose:  Close previously opened file.
  583.   Control Block at Call:  FHANDLE = file handle.
  584.   Control Block at Return:  CONDCODE = error code.
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.                                         7
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.   XFSAVE (Save File)
  599.   Purpose:  Create file with contents equal to specified memory block.
  600.   Control Block at Call:  FNAME = file path and name.  BLKADR/BLKSIZE = address
  601.   and size of memory block to provide file contents.  BUFADR/BUFSIZE = address
  602.   and size of conventional memory buffer.
  603.   Control Block at Return:  CONDCODE = error code.
  604.   Details:
  605.      The file cannot already be open.  The file is both created and closed by
  606.   this routine.
  607.      This routine will replace any previously existing file named FNAME.
  608.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  609.   block is not overlapped by BUFADR/BUFSIZE.
  610.      If this routine is called with BUFSIZE = 0, then EASYX will automatically
  611.   supply a buffer.
  612.  
  613.   XFLOAD (Load File)
  614.   Purpose:  Load file contents to specified memory block.
  615.   Control Block at Call:  FNAME = file path and name.  BLKADR/BLKSIZE = address
  616.   and size of memory block to receive file contents.  BUFADR/BUFSIZE = address
  617.   and size of conventional memory buffer.
  618.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  619.   BLKSIZE = actual number of bytes transferred.
  620.   Details:
  621.      The file cannot already be open.  The file is both opened and closed by
  622.   this routine.
  623.      The value of BLKSIZE as of call is interpreted as an upper limit on the
  624.   number of bytes to transfer.  The entire file is loaded provided that it does
  625.   not contain more than BLKSIZE bytes.
  626.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  627.   block is not overlapped by BUFADR/BUFSIZE.
  628.      If this routine is called with BUFSIZE = 0, then EASYX will automatically
  629.   supply a buffer.
  630.  
  631.   XFWRITE (Write to File)
  632.   Purpose:  Write specified memory block to specified location in open file.
  633.   Control Block at Call:  FHANDLE = file handle.  FPTR/FPTRMODE = file pointer
  634.   setting for beginning of transfer.  BLKADR/BLKSIZE = address and size of
  635.   memory block to provide file contents.  BUFADR/BUFSIZE = address and size of
  636.   conventional memory buffer.
  637.   Control Block at Return:  CONDCODE = error code.
  638.   Details:
  639.      The file must be opened with XFOPEN or XFCREATE before using this routine.
  640.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  641.   block is not overlapped by BUFADR/BUFSIZE.
  642.      Sequential transfers should set FPTRMODE = 3 for fastest execution.
  643.  
  644.   XFREAD (Read From File)
  645.   Purpose:  Load specified memory block from specified location in open file.
  646.   Control Block at Call:  FHANDLE = file handle.  FPTR/FPTRMODE = file pointer
  647.   setting for beginning of transfer.  BLKADR/BLKSIZE = address and size of
  648.   memory block to receive file contents.  BUFADR/BUFSIZE = address and size of
  649.   conventional memory buffer.
  650.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  651.   BLKSIZE = the actual number of bytes transferred.
  652.  
  653.  
  654.  
  655.                                         8
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.   Details:
  663.      The file must be opened with XFOPEN or XFCREATE before using this routine.
  664.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  665.   block is not overlapped by BUFADR/BUFSIZE.
  666.      Sequential transfers should set FPTRMODE = 3 for fastest execution.
  667.  
  668.  
  669.        The following C program illustrates the usage of some of the above
  670.   procedures.  A BASIC translation of this program is in EASYXEX2.BAS.
  671.  
  672.  
  673.   Example 2:  EASYX File Management
  674.   _____________________________________________________________________________
  675.   #include <stdio.h>
  676.   #include <string.h>
  677.   #include <easyx.h>
  678.  
  679.   void main (void)
  680.   {
  681.     int i;
  682.     long errcode, nobytes, xaddress, xsize, handle, arrayaddress;
  683.     int array[100];
  684.     struct xfile fb;                 /*Declare file control block*/
  685.  
  686.     errcode = INITXLIB();            /*Initialize XLIB*/
  687.     if(errcode != 0)
  688.     {
  689.       printf("Library initialization error:  %lX\n",errcode);
  690.       return;
  691.     }
  692.  
  693.     nobytes = 0x10000;               /*Allocate 64k of extended memory*/
  694.     errcode = XMALLOC(nobytes,&xaddress,&xsize,&handle);
  695.     if(errcode != 0)
  696.     {
  697.       printf("Extended memory allocation error:  %lX\n",errcode);
  698.       return;
  699.     }
  700.  
  701.     for(i = 0; i < 100; i++)         /*Put something in array[]*/
  702.       array[i] = i;
  703.  
  704.     arrayaddress = LINADR(array);    /*Compute linear address of array[]*/
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.                                         9
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.     fb.condcode = 0;                 /*Set control block to create file*/
  727.     strcpy(fb.fname,"junk.dat");     /*Specify file name*/
  728.     fb.blkadr = arrayaddress;        /*Will transfer array[] to the file*/
  729.     fb.blksize = 200;                /*There are 200 bytes in array[]*/
  730.     fb.bufsize = 0;                  /*Force XLIB to use its internal buffer*/
  731.     XFSAVE(&fb);                     /*Create file and save array[] to it*/
  732.     if(fb.condcode != 0)
  733.     {
  734.       printf("File save error:  %lX\n",fb.condcode);
  735.       return;
  736.     }
  737.  
  738.     XFOPEN(&fb);                     /*Reopen the file*/
  739.     if(fb.condcode != 0)
  740.     {
  741.       printf("File open error:  %lX\n",fb.condcode);
  742.       return;
  743.     }
  744.  
  745.     fb.blkadr = xaddress;         /*Prepare to transfer the file to extended*/
  746.     fb.blksize = 100;             /*Will transfer only 100 bytes*/
  747.     fb.fptrmode = 0;              /*File pointer is relative to start of file*/
  748.     fb.fptr = 100;                /*Set file pointer to 50th element*/
  749.     XFREAD(&fb);                  /*Read last 50 elements to extended*/
  750.     if(fb.condcode != 0)
  751.     {
  752.       printf("File read error:  %lX\n",fb.condcode);
  753.       return;
  754.     }
  755.  
  756.     MOVMEM(arrayaddress,xaddress,100); /*Transfer file contents back to array[]
  757.  
  758.     XFCLOSE(&fb);                      /*Close the file*/
  759.     if(fb.condcode != 0)
  760.     {
  761.       printf("File close error:  %lX\n",fb.condcode);
  762.       return;
  763.     }
  764.  
  765.     errcode = XFREE(handle);           /*Release extended memory*/
  766.     if(errcode != 0)
  767.     {
  768.       printf("Memory release error:  %lX\n",errcode);
  769.       return;
  770.     }
  771.   }
  772.   _____________________________________________________________________________
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.                                         10