home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- EASYX PROGRAMMER'S MANUAL
- VERSION 1.2
-
- (DOS Extender Library)
-
- TechniLib Company
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright 1993 1994, by TechniLib (TM) Company
- All Rights Reserved
-
-
-
-
-
-
- TERMS OF USE AND DISTRIBUTION
-
-
- XLIB is a shareware product; therefore, unregistered copies of XLIB are
- made available free of charge so that potential purchasers will have the
- opportunity to examine and test the software before committing payment.
- Distribution of unregistered copies of XLIB to other potential users is also
- permitted and appreciated. However, usage and distribution of XLIB must
- conform to the following conditions. In the following statement, the term
- "commercial distribution," includes shareware distribution.
-
- 1) XLIB and accompanying software must be distributed together in copies of
- the original archive provided by TechniLib. Neither the archive nor
- individual files therein may be modified.
-
- 2) The XLIB archive may be distributed in combination with other shareware
- products; however, the XLIB archive may not be distributed with other
- commercially distributed software without written consent of TechniLib.
-
- 3) Copies of XLIB which have been used to develop software for commercial
- distribution must be registered before such software is marketed. Copies of
- XLIB which have been used to develop noncommercial software must be registered
- if such software is to be regularly used either by the developer or others.
-
- 4) Commercially distributed software must embed XLIB procedures in the
- software code. Files contained in the XLIB archive may not be placed in the
- distribution media.
-
- 5) XLIB is designed to offer a set of services to other executable code. XLIB
- may not be used to develop software for commercial distribution which will
- essentially offer any of these same services to other executable code.
- Exceptions to this condition require written consent of TechniLib.
-
- 6) Rights afforded by registering a single copy of XLIB pertain only to a
- single computer.
-
- 7) XLIB may be registered for a fee of $40.00 per copy. Accompany payment
- with the registration form included in the XLIB archive. Registrants will be
- entitled to the most recent version of the XLIB archive.
-
-
- DISCLAIMER OF WARRANTY
-
-
- XLIB AND ALL ACCOMPANYING SOFTWARE AND LITERATURE ARE DISTRIBUTED WITH
- THE EXCLUSION OF ANY AND ALL IMPLIED WARRANTIES, AND WITH THE EXCLUSION OF
- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. TechniLib
- SHALL HAVE NO LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- RESULTING FROM THE USE OF XLIB OR ACCOMPANYING MATERIALS. The user assumes
- the entire risk of using this software.
-
-
- Copyright 1993 1994, by TechniLib (TM) Company
- All Rights Reserved
-
-
-
-
-
-
- TABLE OF CONTENTS
-
-
- CHAPTERS
- Page
- 1. Introduction 1
- 2. Initialization of EASYX 2
- 3. Memory Management 3
- 4. Memory-Mapped Input/Output 5
- 5. File Management 6
-
-
- EXAMPLES
- Page
- 1. EASYX Memory Management 4
- 2. EASYX File Management 9
-
-
-
-
-
-
- 1. Introduction
-
-
- EASYX is a DOS extender library intended for programmers who are
- unfamiliar with assembly language. EASYX allows real-mode high-level
- languages to perform transfers between extended memory and conventional memory
- or between extended memory and disk files. Many programmers need a DOS
- extender merely to afford real-mode languages access to extended memory. In
- such cases, EASYX is a simple and powerful alternative.
- EASYX is actually little more than a real-mode interface to XLIB. The
- source code for EASYX is supplied in the XLIB archive (EASYX.ASM). Assembly
- language programmers may be interested in examining this code to learn more
- about working with XLIB. This code has been assembled and then linked with
- XLIB.LIB to create EASYX.LIB.
- The EASYX library is provided in two formats - one for Microsoft
- languages and the other for Borland languages. Microsoft programmers should
- use EASYX.LIB. Borland programmers should use EASYXB.LIB. The respective C
- header files are EASYX.H and EASYXB.H. Programmers using other languages will
- have to write their own prototypes for EASYX procedures. These prototypes
- should declare all EASYX procedures as far procedures conforming to the PASCAL
- calling and naming convention. Prototypes for Microsoft BASIC 7.0 are
- presented in the files EASYXEX1.BAS and EASYXEX2.BAS.
- The programmer might prefer to use EASYXE.LIB rather than EASYX.LIB. The
- former has CPU exception trapping capabilities whereas the latter does not.
- EASYXE.LIB will always trap exceptions occurring in protected mode. It can
- also trap real-mode exceptions provided that a DPMI 1.0 host is installed.
- Borland programmers should use EASYXEB.LIB. C and C++ programmers should
- continue to use EASYX.H or EASYXB.H for header files.
- Most EASYX procedures can return error codes. These are always XLIB
- error codes. The codes are explained in the XLIB documentation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 2. Initialization of EASYX
-
-
- EASYX requires no initialization; however, the XLIB library which has
- been linked with EASYX must be initialized before any EASYX procedures are
- called. XLIB is initialized by calling INITXLIB. INITXLIB returns an error
- code in DX:AX; therefore, it should be implemented as a long integer function.
- The following code demonstrates initialization in Microsoft C:
-
-
- extern long __far __pascal INITXLIB(void);
-
- void main(void)
- {
- long errcode;
- errcode = INITXLIB();
- if(errcode != 0)
- {
- printf("Initialization error: %lX",errcode);
- return;
- }
- .
- .
- .
-
- An explanation of possible error codes is explained in the XLIB
- documentation. The most common error is caused by insufficient conventional
- memory. INITXLIB will attempt to allocate a small amount of conventional
- memory through DOS; however, many high-level languages automatically claim all
- available DOS memory, even though only a small percentage of this memory may
- actually be used. The programmer must therefore release a portion of this
- memory back to DOS before calling INITXLIB. This process is illustrated for
- the Borland Turbo Assembler in the file EXAMP1B.ASM, and for Microsoft BASIC
- in EASYXEX1.BAS. C and C++ programmers need not be concerned with this matter
- because these languages allocate DOS memory dynamically.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
- 3. Memory Management
-
-
- High-level languages confined to real mode are incapable of addressing
- extended memory; consequently, such languages must communicate with extended
- memory through buffers in conventional memory. EASYX provides several
- procedures to facilitate this process.
- Extended memory should always be allocated with the procedure XMALLOC
- before it is addressed. Attempted transfers to or from unallocated memory may
- lead to page faults (exception 14), or to corruption of resident software.
- XMALLOC returns a long integer error code; therefore, it should be implemented
- as a long integer function. The following Microsoft C prototype shows the
- structure of XMALLOC:
-
-
- extern long __far __pascal XMALLOC(long nobytes, long __far *address,
- long __far *size, long __far *handle);
-
- where:
- nobytes = The requested size for the extended memory block.
- *address = A far pointer to a long integer variable which will receive the
- linear address of the allocated block.
- *size = A far pointer to a long integer variable which will receive the
- actual size of the allocated extended memory block. The actual
- size will always be at least as large as the requested size.
- *handle = A far pointer to a long integer variable which will receive a
- handle for the allocated extended memory block. The handle must
- be used to release the block.
-
-
- An extended memory block can be released with the XFREE procedure. XFREE
- is also a long integer function which returns an error code. The C prototype
- of this procedure is:
-
-
- extern long __far __pascal XFREE(long handle);
-
- where: handle = The handle assigned to the block by XMALLOC.
-
-
- All extended memory is automatically released upon program termination;
- consequently, XFREE will not be necessary for most programs.
- Transfers between conventional memory and extended memory can be
- accomplished with the MOVMEM procedure. The prototype for MOVMEM is:
-
-
- extern void __far __pascal MOVMEM(long destadr, long sourceadr,long nobytes);
-
- where:
- destadr = The linear address of the destination memory.
- sourceadr = The linear address of the source memory.
- nobytes = The number of bytes to be transferred.
-
-
-
-
-
- 3
-
-
-
-
-
-
- MOVMEM may actually be used to transfer memory between any source and
- destination. The destination block and source block may also be overlapped.
- MOVMEM transfers are faster than XMS or INT 15H because MOVMEM uses 32-
- bit instructions. MOVMEM also exposes to less risk of losing an interrupt.
- MOVMEM is a reentrant procedure, so it may be safely called within
- interrupt handlers. When MOVMEM is being used in a hardware interrupt
- handler, the handler should be installed after the call to INITXLIB to prevent
- a call to MOVMEM before protected-mode structures have been initialized.
- Real-mode programs use segment addresses instead of linear addresses.
- EASYX includes a procedure called LINADR which computes linear addresses from
- segment addresses. The prototype for LINADR is:
-
-
- extern long __far __pascal LINADR(void __far *ptr);
-
-
- The following program uses the procedures presented in this section. The
- file EASYXEX1.BAS contains a Microsoft BASIC 7.0 version of the program.
-
-
- Example 1: EASYX Memory Management
- _____________________________________________________________________________
- #include <stdio.h>
- #include <easyx.h>
-
- void main(void)
- {
- long errcode, nobytes, xaddress, xsize, xhandle, bufferaddress;
- long buffer[1024]; /*4k buffer*/
-
- errcode = INITXLIB(); /*Initialize XLIB*/
- if(errcode != 0)
- {
- printf("Library initialization error: %lX\n",errcode);
- return;
- }
-
- nobytes = 0x10000; /*Allocate 64k of extended memory*/
- errcode = XMALLOC(nobytes, &xaddress, &xsize, &xhandle);
- if(errcode != 0)
- {
- printf("Memory allocation error: %lX\n",errcode);
- return;
- }
-
- bufferaddress = LINADR(buffer); /*Get linear address of buffer*/
- MOVMEM(xaddress, bufferaddress, 4096); /*Transfer buffer to extended*/
- MOVMEM(bufferaddress, xaddress, 4096); /*Transfer extended to buffer*/
-
- errcode = XFREE(xhandle); /*Release the extended memory*/
- if(errcode != 0)
- printf("Memory release error: %lX\n",errcode);
- }
- _____________________________________________________________________________
-
-
-
- 4
-
-
-
-
-
-
- 4. Memory-Mapped Input/Output
-
-
- On 386 and higher machines, memory reads and writes may undergo address
- translation so that the address which is physically accessed may be different
- from the address specified in the read/write instruction. The physically
- accessed address is the "physical address." The address specified by the
- read/write instruction is the "logical address." Normally programmers need
- not be concerned with the difference; however, this is not the case if the
- program must access an IO device which maps to a fixed physical address. In
- such cases, the programmer must obtain a logical address which corresponds to
- the physical address of the IO device. EASYX contains a procedure called
- MAPIOMEM which will map a specified physical address into a logical address
- space. MAPIOMEM is a long integer function which returns an error code. The
- prototype for MAPIOMEM is:
-
-
- extern long __far __pascal MAPIOMEM(long physaddress, long size,
- long __far *logaddress);
-
- where:
- physaddress = The beginning physical address for the IO device.
- size = The size of the physical address block in bytes.
- *logaddress = A far pointer to a long integer which is to receive the assigned
- logical address. Access the IO device at this address.
-
-
- MAPIOMEM will sometimes return errors upon attempts to map physical
- addresses in the first megabyte.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 5
-
-
-
-
-
-
- 5. File Management
-
-
- EASYX includes procedures which can transfer data between extended memory
- and files. These procedures can load files to extended memory or save
- extended memory to files. They can read and write files either sequentially
- or randomly.
- All EASYX file management routines will receive and return values in a
- contiguous block of memory called a "file control block" (not to be confused
- with DOS file control blocks). The file control block must be located in
- conventional memory and must have the following form:
-
-
- Field Name Field Type Field Description
- ---------- ---------- -----------------
- CONDCODE DWORD Condition code from file operation
- FNAME BYTE[68] File path and name (zero terminated string)
- FHANDLE WORD File handle assigned by DOS
- FPTRMODE WORD File pointer mode
- FPTR DWORD File pointer
- BLKADR DWORD Memory source/destination address
- BLKSIZE DWORD Size of source/destination block in bytes
- BUFADR DWORD Buffer address (conventional memory)
- BUFSIZE WORD Buffer size in bytes
- CONTROL WORD Control word
-
-
- CONDCODE is used to return error codes. CONDCODE should be situated at
- the starting address of the control block.
- FNAME is a zero-terminated ASCII string defining the file path and name.
- There cannot be more than 68 characters in this string, including the
- termination character.
- BLKADR and BLKSIZE define the source/destination memory block for the
- transfer. This block may be in either conventional or extended memory.
- BLKADR is a linear address.
- XLIB uses DOS to access the disk. DOS cannot read or write to extended
- memory; consequently, a conventional memory buffer must be set up for the DOS
- transfers. File management routines shift to protected mode to perform
- transfers between the buffer and the source/destination memory. BUFADR and
- BUFSIZE define the conventional memory buffer. BUFADR is a linear address.
- For fastest transfers, the memory block and the buffer should be DWORD
- aligned and should have sizes equal to an integer multiple of four.
- FPTR and FPTRMODE specify the file pointer setting to be used before
- intrafile transfers to or from the disk. FPTRMODE specifies how FPTR is to be
- interpreted. The following values are valid for FPTRMODE:
-
-
- FPTRMODE FPTR Interpretation
- -------- -------------------
- 0 Unsigned offset from the beginning of the file
- 1 Signed offset from the current file pointer
- 2 Signed offset from the end of the file
- 3 FPTR is ignored. Use current file pointer (sequential mode)
-
-
-
-
- 6
-
-
-
-
-
-
- CONTROL is not used in the present version of EASYX. All bits in control
- should be set to zero.
- Since these routines perform disk operations, special precautions should
- be taken to ensure that parameters in the file control block are properly
- defined before performing calls. In particular, one should always make sure
- that the source/destination memory block and the conventional memory buffer
- are properly defined. A safe rule is to simply set the buffer size to zero
- because this forces EASYX to supply a buffer when opening or creating the
- file.
- EASYX file routines should not be called within interrupt handlers
- because all of these routines use DOS.
- All EASYX file routines receive a single argument; namely, the far
- address of the control block. Prototypes for the file routines are:
-
-
- extern void __far __pascal XFCREATE(void __far *controlblock);
- extern void __far __pascal XFOPEN(void __far *controlblock);
- extern void __far __pascal XFCLOSE(void __far *controlblock);
- extern void __far __pascal XFLOAD(void __far *controlblock);
- extern void __far __pascal XFSAVE(void __far *controlblock);
- extern void __far __pascal XFREAD(void __far *controlblock);
- extern void __far __pascal XFWRITE(void __far *controlblock);
-
-
- The following is a detailed explanation of each of these procedures:
-
-
- XFCREATE (Create File)
- Purpose: Create and open a new file of specified name in specified directory.
- Control Block at Call: FNAME = file path and name.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- FHANDLE = file handle assigned by DOS. If the procedure is called with
- BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
- buffer.
- Details:
- If the file already exists, then it will be truncated to zero length.
- Files created by this routine will be given both read and write access.
-
- XFOPEN (Open File)
- Purpose: Open existing file of specified name in specified directory.
- Control Block at Call: FNAME = file path and name.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- FHANDLE = file handle assigned by DOS. If the procedure is called with
- BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
- buffer.
- Details: The file is opened for both read and write access.
-
- XFCLOSE (Close File)
- Purpose: Close previously opened file.
- Control Block at Call: FHANDLE = file handle.
- Control Block at Return: CONDCODE = error code.
-
-
-
-
-
-
- 7
-
-
-
-
-
-
- XFSAVE (Save File)
- Purpose: Create file with contents equal to specified memory block.
- Control Block at Call: FNAME = file path and name. BLKADR/BLKSIZE = address
- and size of memory block to provide file contents. BUFADR/BUFSIZE = address
- and size of conventional memory buffer.
- Control Block at Return: CONDCODE = error code.
- Details:
- The file cannot already be open. The file is both created and closed by
- this routine.
- This routine will replace any previously existing file named FNAME.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- If this routine is called with BUFSIZE = 0, then EASYX will automatically
- supply a buffer.
-
- XFLOAD (Load File)
- Purpose: Load file contents to specified memory block.
- Control Block at Call: FNAME = file path and name. BLKADR/BLKSIZE = address
- and size of memory block to receive file contents. BUFADR/BUFSIZE = address
- and size of conventional memory buffer.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- BLKSIZE = actual number of bytes transferred.
- Details:
- The file cannot already be open. The file is both opened and closed by
- this routine.
- The value of BLKSIZE as of call is interpreted as an upper limit on the
- number of bytes to transfer. The entire file is loaded provided that it does
- not contain more than BLKSIZE bytes.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- If this routine is called with BUFSIZE = 0, then EASYX will automatically
- supply a buffer.
-
- XFWRITE (Write to File)
- Purpose: Write specified memory block to specified location in open file.
- Control Block at Call: FHANDLE = file handle. FPTR/FPTRMODE = file pointer
- setting for beginning of transfer. BLKADR/BLKSIZE = address and size of
- memory block to provide file contents. BUFADR/BUFSIZE = address and size of
- conventional memory buffer.
- Control Block at Return: CONDCODE = error code.
- Details:
- The file must be opened with XFOPEN or XFCREATE before using this routine.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- Sequential transfers should set FPTRMODE = 3 for fastest execution.
-
- XFREAD (Read From File)
- Purpose: Load specified memory block from specified location in open file.
- Control Block at Call: FHANDLE = file handle. FPTR/FPTRMODE = file pointer
- setting for beginning of transfer. BLKADR/BLKSIZE = address and size of
- memory block to receive file contents. BUFADR/BUFSIZE = address and size of
- conventional memory buffer.
- Control Block at Return: CONDCODE = error code. If CONDCODE = 0, then
- BLKSIZE = the actual number of bytes transferred.
-
-
-
- 8
-
-
-
-
-
-
- Details:
- The file must be opened with XFOPEN or XFCREATE before using this routine.
- BLKADR/BLKSIZE may define a conventional memory block provided that this
- block is not overlapped by BUFADR/BUFSIZE.
- Sequential transfers should set FPTRMODE = 3 for fastest execution.
-
-
- The following C program illustrates the usage of some of the above
- procedures. A BASIC translation of this program is in EASYXEX2.BAS.
-
-
- Example 2: EASYX File Management
- _____________________________________________________________________________
- #include <stdio.h>
- #include <string.h>
- #include <easyx.h>
-
- void main (void)
- {
- int i;
- long errcode, nobytes, xaddress, xsize, handle, arrayaddress;
- int array[100];
- struct xfile fb; /*Declare file control block*/
-
- errcode = INITXLIB(); /*Initialize XLIB*/
- if(errcode != 0)
- {
- printf("Library initialization error: %lX\n",errcode);
- return;
- }
-
- nobytes = 0x10000; /*Allocate 64k of extended memory*/
- errcode = XMALLOC(nobytes,&xaddress,&xsize,&handle);
- if(errcode != 0)
- {
- printf("Extended memory allocation error: %lX\n",errcode);
- return;
- }
-
- for(i = 0; i < 100; i++) /*Put something in array[]*/
- array[i] = i;
-
- arrayaddress = LINADR(array); /*Compute linear address of array[]*/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 9
-
-
-
-
-
-
- fb.condcode = 0; /*Set control block to create file*/
- strcpy(fb.fname,"junk.dat"); /*Specify file name*/
- fb.blkadr = arrayaddress; /*Will transfer array[] to the file*/
- fb.blksize = 200; /*There are 200 bytes in array[]*/
- fb.bufsize = 0; /*Force XLIB to use its internal buffer*/
- XFSAVE(&fb); /*Create file and save array[] to it*/
- if(fb.condcode != 0)
- {
- printf("File save error: %lX\n",fb.condcode);
- return;
- }
-
- XFOPEN(&fb); /*Reopen the file*/
- if(fb.condcode != 0)
- {
- printf("File open error: %lX\n",fb.condcode);
- return;
- }
-
- fb.blkadr = xaddress; /*Prepare to transfer the file to extended*/
- fb.blksize = 100; /*Will transfer only 100 bytes*/
- fb.fptrmode = 0; /*File pointer is relative to start of file*/
- fb.fptr = 100; /*Set file pointer to 50th element*/
- XFREAD(&fb); /*Read last 50 elements to extended*/
- if(fb.condcode != 0)
- {
- printf("File read error: %lX\n",fb.condcode);
- return;
- }
-
- MOVMEM(arrayaddress,xaddress,100); /*Transfer file contents back to array[]
-
- XFCLOSE(&fb); /*Close the file*/
- if(fb.condcode != 0)
- {
- printf("File close error: %lX\n",fb.condcode);
- return;
- }
-
- errcode = XFREE(handle); /*Release extended memory*/
- if(errcode != 0)
- {
- printf("Memory release error: %lX\n",errcode);
- return;
- }
- }
- _____________________________________________________________________________
-
-
-
-
-
-
-
-
-
-
- 10