Dec 132017
 
XMSLIB provides a high-level C interface to XMS control functions for common operations such as allocating and freeing XMS extended memory blocks (EMBs).
File XMSLB130.ZIP from The Programmer’s Corner in
Category C Source Code
XMSLIB provides a high-level C interface to XMS control functions for common operations such as allocating and freeing XMS extended memory blocks (EMBs).
File Name File Size Zip Size Zip Type
WHATSNEW.130 412 262 deflated
XMSLIB.DOC 21344 6301 deflated
XMSLIB.H 3260 911 deflated
XMSLIB.HPP 3340 956 deflated
XMSLIBC.OBJ 5267 3192 deflated
XMSLIBL.OBJ 5279 3210 deflated
XMSLIBM.OBJ 5245 3184 deflated
XMSLIBS.OBJ 5233 3173 deflated
XMSTEST.C 6012 1589 deflated

Download File XMSLB130.ZIP Here

Contents of the XMSLIB.DOC file


XMSLIB
C Interface to XMS Functions
XMSLIB version 1.3
by James W. Birdsall
07/27/91


1. INTRODUCTION
---------------

XMSLIB provides a high-level interface to XMS control functions for common
operations such as allocating and freeing XMS extended memory blocks (EMBs)
and copying data to and from EMBs. A raw interface has been included to allow
more exotic functions which are not directly supported.

1.1 LEGALESE
------------

XMSLIB is not in the public domain. It is copyright 1991 by James W.
Birdsall, all rights reserved. Permission is granted to do the following:

You may freely redistribute this archive, so long as it contains
all the files listed here {XMSLIB.DOC, XMSLIBS.OBJ, XMSLIBC.OBJ,
XMSLIBM.OBJ, XMSLIBL.OBJ, XMSTEST.C, XMSLIB.H, XMSLIB.HPP} intact
and unmodified.

You may use the object files in programs for your own use. You
may not distribute programs linked with these object files.

Payment of the $5 shareware registration fee ($50 for commercial use)
grants the following additional permissions:

You may obtain the source to XMSLIB, upon request. You may modify
the source as necessary for use in your programs. However, you may
not redistribute either the original or modified source.

You may distribute programs linked with either the original
object files or object files generated from source you have
modified, without royalty.

For the purposes of this license, commercial use is defined as use by an
incorporated entity in a software product that is regarded as the product
of the corporation, no matter how the software product is distributed, but
only if 100 or more copies of the product are expected to be made.

The contents of this archive, and all other related files, information,
and services are provided as-is. While every effort has been made to ensure
that the files, information, and services are accurate and correct, the
author cannot be held liable for damages arising out of the use of or
inability to use this product.

Information on contacting the author is provided at the end of this
file.


2. USE
------

XMSLIB is provided as an object file for maximum flexibility. It is
written in Turbo Assembler 2.5, to be compatible with Borland C++ 2.0. Since
Borland C++ has the same calling conventions as Turbo C(++), XMSLIB is
compatible with Turbo C(++).
According to the documentation for Microsoft C 6.0, the calling
conventions used by MSC are essentially the same. XMSLIB should be compatible
with MSC also, but extensive testing has not been done. What tests could
be performed worked.

XMSLIB is provided for small, medium, compact, and large models. The model
for which the object is intended is indicated by the last letter of the
filename proper, which is the same as the first letter of the model. For
example, XMSLIBL.OBJ is the large-model object. The small object should
probably work with the tiny model, but it has not been tested. Huge model is
not supported, but should require only trivial changes to the source.

To use XMSLIB, choose the appropriate object for the model in which the
rest of your program is compiled, and include that object. Note that every
source file which uses XMSLIB functions should include the file XMSLIB.H.

If you are compiling and linking in the Integrated Development Environment
of Turbo C(++), you have two options:

1) Include the name of the appropriate object in the project file.
For example, if you are working in the compact memory model, you
should include XMSLIBC.OBJ in your project file.

2) Add the appropriate object file to the appropriate standard library
file. To do this, you will need to use the librarian utility
(TLIB.EXE) provided by Borland. For example, the command

tlib cc+xmslibc

will add the XMSLIBC.OBJ file to the standard library file for
the compact memory model, assuming both files are in the current
directory.

If you are using the command-line compiler to compile and/or link, simply
place the full name of the XMSLIB object on the command line. If you are
linking manually (using LINK, TLINK, et al.), simply place XMSLIB in with the
names of the other object files being linked. Examples follow.

An example program, XMSTEST.C, has been included. To use it, simply
compile it in whatever memory model you choose and link it with the
appropriate XMSLIB object for that memory model. For example, using the
Borland C++ command-line compiler, the following command would compile
XMSTEST.C in the medium model and link it with XMSLIBM.OBJ:

bcc -mm xmstest.c xmslibm.obj

Users of Turbo C(++) can simply substitute "tcc" for "bcc". The following
two commands perform the same function, but demonstrate using TLINK
directly:

bcc -mm -c xmstest.c
tlink c0m xmstest xmslibm, xmstest, , cm

Again, users of Turbo C(++) can simply substitute "tcc" for "bcc". TLINK is
the same for both packages. The files "c0m" and "cm" on the TLINK command
line are the standard medium-model startup object and medium-model library,
respectively.

2.1 USE WITH C++
----------------

Use of XMSLIB with C++ is very similar to use with C. C++ files which
use XMSLIB functions should include XMSLIB.HPP instead of XMSLIB.H. If you
forget to include it, or include the wrong one, you will probably see
"Undefined symbol" errors when linking.


3. GENERAL CONSIDERATIONS
-------------------------

XMSLIB provides a set of functions which are intended to be orthogonal
with the standard C functions malloc()/free(), and the Turbo C function
coreleft().

One point that cannot be stressed sufficiently is that the library
initialization function XMMlibinit() _must_ be called before any other
XMSLIB calls are made. Failure to do so will result in undefined behavior
or crash. One of the important things that XMMlibinit() does is determine
whether there is an XMS driver in the system at all.

All files which call XMSLIB functions should #include the file XMSLIB.H
or XMSLIB.HPP, as appropriate. These files define the return and error code
symbols shown in section 5, declare the global variables provided by XMSLIB,
and provide prototypes for the XMSLIB functions.


4. LIBRARY FACILITIES
---------------------

4.1 GLOBAL VARIABLES
--------------------

XMSLIB provides the following global variables, as shown in the header
files XMSLIB.H and XMSLIB.HPP:

4.1.1 _XMMerror
---------------

_XMMerror is an unsigned char which contains the XMS driver error
code from the last XMS driver call. If there was no error, it will be 0.
A list of error code values and symbolic values is in section 5.

4.1.2 _XMMversion
-----------------

_XMMversion is an unsigned int which contains the XMS version that the
XMS driver implements. It is in packed BCD format. For example, if the XMS
version is 2.0, the value of _XMMversion will be 0x0200. The high byte of
_XMMerror represents two digits to the left of the decimal point (one digit
per nibble) and the low byte represents two digits to the right of the
decimal point (one digit per nibble).

4.1.3 xmslib_vers_vers, xmslib_vers_date, xmslib_vers_time
----------------------------------------------------------

These variables are null-terminated strings containing information about
the name and version of the library, the date of compilation, and the time
of compilation, respectively.

4.2 FUNCTIONS
-------------

All functions set the variable _XMMerror. If the function completed
successfully, _XMMerror is set to 0. If there was an error, _XMMerror is
set to the appropriate error code. Thus, it is always possible to check
the value of _XMMerror after a function call to check for errors. However,
many functions also indicate success or error by their return value. Those
functions where the return value may be ambiguous are noted, and it is
recommended that _XMMerror be checked instead of the return value.

4.2.1 XMMlibinit()
------------------

int XMMlibinit(void)

This function initializes the library. It _must_ be called before any
other XMSLIB calls are made. It returns 0 on success, XMMOOPS if there was
an XMS driver error, or NOXMM if an XMS driver was not detected.

4.2.2 XMMgetversion()
---------------------

unsigned int XMMgetversion(void)

This function returns the XMS version implemented by the XMS driver. It
is in packed BCD format, the same as in the global variable _XMMversion (see
above).
The value of _XMMerror should be checked after calling this function.
If an error occurred, _XMMerror will be set to the error code. If the function
completed successfully, _XMMerror will be 0.

4.2.3 XMMcoreleft()
-------------------

unsigned long XMMcoreleft(void)

This function returns the size of the largest EMB, in bytes. Since it is
not possible to allocate a single block larger than the largest EMB, the
size of the largest EMB is generally more useful than the total amount of
free XMS extended memory.
Note that when all EMBs have been allocated, the driver itself returns an
error (0xA0, XMM_NOFREEX). This behavior is masked by the XMMcoreleft()
function -- if there are no free EMBs, XMMcoreleft() returns 0L instead of
an error.
The value of _XMMerror should be checked after calling this function.
If an error occurred, _XMMerror will be set to the error code. If the function
completed successfully, _XMMerror will be 0.

4.2.4 XMMallcoreleft()
----------------------

unsigned long XMMallcoreleft(void)

This function returns the total amount of free XMS extended memory, in
bytes.
Note that when all EMBs have been allocated, the driver itself returns an
error (0xA0, XMM_NOFREEX). This behavior is masked by the XMMallcoreleft()
function -- if there are no free EMBs, XMMallcoreleft() returns 0L instead of
an error.
The value of _XMMerror should be checked after calling this function.
If an error occurred, _XMMerror will be set to the error code. If the function
completed successfully, _XMMerror will be 0.

4.2.5 XMMalloc()
----------------

int XMMalloc(unsigned long bytes)
bytes -- number of bytes to allocate

This function allocates an EMB. It takes the given number of bytes and
rounds upward to the next kilobyte (the XMS driver can allocate EMBs only
in units of kilobytes) and allocates that many kilobytes. It returns the EMB
handle assigned by the XMS driver.
The value of _XMMerror should be checked after calling this function.
If an error occurred, _XMMerror will be set to the error code. If the
function completed successfully, _XMMerror will be 0.
Note that EMBs cannot be allocated in units smaller than a kilobyte.

Requesting one byte will allocate 1024 bytes; requesting 1025 bytes will
allocate 2048. However, requesting 0 bytes will allocate a handle but no
bytes. This is explicitly allowed by the XMS specification.

4.2.6 XMMfree()
---------------

int XMMfree(int handle)
handle -- EMB handle to free

This function accepts an EMB handle obtained from the XMMalloc() function
or directly from the XMS driver, and releases it and the EMB allocated to it.
If an error occurred, XMMfree() returns XMMOOPS and _XMMerror will be set to
the error code. If the function completed successfully, XMMfree() returns 0
and _XMMerror will be 0.

4.2.7 _XMMcopy()
------------------

int _XMMcopy(unsigned long copylen, int shan, unsigned long soff,
int dhan, unsigned long doff)
copylen -- number of bytes to be copied
shan -- EMB handle of source
soff -- offset in shan of source, or far pointer to source if
source in conventional memory
dhan -- EMB handle of destination
doff -- offset in dhan of destination, or far pointer to destination
if destination in conventional memory

This function allows painless copying from conventional memory to an EMB,
from an EMB to conventional memory, from one EMB to another, or even from
one point in conventional memory to another. Areas larger than 64K can be
copied without special treatment. Macros XMMcopyto() and XMMcopyfrom()
(see below) are provided for even easier copying from conventional memory
to an EMB and vice versa, respectively.
Copylen bytes of data are copied. If shan is nonzero, it is assumed to be
the handle of an EMB, and soff is treated as a byte offset into the EMB owned
by shan. If shan is zero, soff is treated as a segment:offset far pointer to
conventional memory. The pair of shan and soff indicate where the data is to
be copied from (the source). Dhan and doff work the same way as shan and soff,

but indicate where the data is to be copied to (the destination).
If an error occurred, XMMOOPS is returned and _XMMerror is set to an error
code. If the function completed successfully, 0 is returned and _XMMerror is
0.
Note that copies of odd numbers of bytes are slower than copies of even
numbers of bytes, and that copies of one byte are even slower. For best
performance, copy even numbers of bytes at a time.

4.2.8 XMMrawcall()
------------------

int XMMrawcall(struct XMMregs *regs)
regs -- pointer to structure holding values for registers

This function is a raw interface directly to the XMS driver. The XMMregs
structure has fields for the AX, BX, DX, SI, and DS registers, which are the
only ones used by the XMS driver. The values in the structure are placed
in the appropriate registers before the XMS driver is called, and the values
in the registers are copied back into the structure after the XMS driver
call returns.
Since the XMS specification provides a uniform error indication,
XMMrawcall() is able to tell if the call performed caused an error. If it
did, XMMOOPS is returned and _XMMerror is set to the error code. If it
completed successfully, 0 is returned and _XMMerror is set to 0. The low byte
of the regBX field of the XMMregs structure will also contain the error code
if an error occurred.
The details of the XMMregs structure are shown in the header file XMSLIB.H.

4.3 MACROS
----------

XMSLIB provides a few macros to make calls to _XMMcopy easier.

4.3.1 XMMcopyto()
-----------------

int XMMcopyto(unsigned long copylen, unsigned char far *source,
int dhan, unsigned long doff)
copylen -- number of bytes to be copied
source -- far pointer to conventional memory source
dhan -- EMB handle of destination
doff -- offset in dhan of destination

This macro allows painless copying from conventional memory to an EMB.
Areas larger than 64K can be copied without special treatment.
Copylen bytes of data are copied. Source is a far pointer to conventional
memory and indicates where the data is to be copied from. Dhan is the handle
of an EMB, and doff is a byte offset into the EMB owned by dhan. The pair of
dhan and doff indicate where the data is to be copied to.
If an error occurred, XMMOOPS is returned and _XMMerror is set to an error
code. If the function completed successfully, 0 is returned and _XMMerror is
0.
Note that copies of odd numbers of bytes are slower than copies of even
numbers of bytes, and that copies of one byte are even slower. For best
performance, copy even numbers of bytes at a time.

4.3.2 XMMcopyfrom()
-------------------

int XMMcopyfrom(unsigned long copylen, int shan, unsigned long soff,
unsigned char far *dest)
copylen -- number of bytes to be copied
shan -- EMB handle of source
soff -- offset in shan of source, or far pointer to source if
source in conventional memory
dest -- far pointer to conventional memory destination.

This macro allows painless copying to conventional memory from an EMB.
Areas larger than 64K can be copied without special treatment.
Copylen bytes of data are copied. Shan is the handle of an EMB, and soff
is a byte offset into the EMB owned by shan. The pair of shan and soff
indicate where the data is to be copied from. Dest is a far pointer to
conventional memory and indicates where the data is to be copied to.
If an error occurred, XMMOOPS is returned and _XMMerror is set to an error
code. If the function completed successfully, 0 is returned and _XMMerror is
0.
Note that copies of odd numbers of bytes are slower than copies of even
numbers of bytes, and that copies of one byte are even slower. For best
performance, copy even numbers of bytes at a time.

5. ERROR CODES
--------------

This section is a list of the error codes to which the global variable
_XMMerror may be set, and the values and meanings thereof.

5.1 INTERNAL CODES
------------------

XMSLIB does not generate any error codes internally.

5.2 XMS DRIVER CODES
--------------------

These codes are defined in the XMS specification and are returned by
the XMS driver. They are saved in _XMMerror by XMSLIB without alteration.

NAME VALUE MEANING
---- ----- -------
XMM_UNIMP 0x80 Function is not implemented

XMM_VDISK 0x81 VDISK device driver was detected

XMM_A20ERROR 0x82 A20 error occurred

XMM_GENERROR 0x83 General driver error occurred

XMM_UNRECERROR 0x84 Unrecoverable driver error occurred

XMM_NOHMA 0x90 HMA (High Memory Area) does not exist

XMM_HMAUSED 0x91 HMA already allocated

XMM_HMATOOBIG 0x92 Request to allocate HMA denied because
amount of HMA requested is less than
minimum parameter given to XMS driver
on its command line

XMM_HMANOALLOC 0x93 HMA is not allocated

XMM_A20STILLEN 0x94 A20 line is still enabled

XMM_NOFREEX 0xA0 All EMBs (Extended Memory Blocks) are
allocated

XMM_NOFREEXHAN 0xA1 No free EMB handles

XMM_BADXHAN 0xA2 EMB handle is invalid

XMM_BADSRCHAN 0xA3 Source EMB handle is invalid

XMM_BADSRCOFF 0xA4 Source offset in EMB is beyond end of EMB

XMM_BADDESTHAN 0xA5 Destination EMB handle is invalid

XMM_BADDESTOFF 0xA6 Destination offset in EMB is beyond end
of EMB

XMM_BADLENGTH 0xA7 Length is invalid

XMM_COPYOVERLAP 0xA8 Overlap in copy request is invalid

XMM_PARITY 0xA9 Parity error was detected

XMM_NOLOCK 0xAA EMB is not locked

XMM_LOCKED 0xAB EMB is locked

XMM_TOOMANYLOCKS 0xAC EMB lock count overflowed

XMM_LOCKFAIL 0xAD EMB lock failed

XMM_UMBSMALLER 0xB0 UMB (Upper Memory Block) of size requested
is not available; however, a smaller UMB
is available

XMM_NOFREEUMB 0xB1 All UMBs are allocated

XMM_BADUMBHAN 0xB2 UMB handle (same as segment address of
start of UMB) is invalid


6. THE END
----------

Technical support via email is available from the following addresses:

INTERNET:
First choice (the following are alternate addresses for the same place):
[email protected]
[email protected]
[email protected]
[email protected]
uunet!uw-coco!amc-gw!picarefy!support

Second choice:
[email protected]

COMPUSERVE:
71261,1731

AMERICA ON-LINE:
GreenTiger

GENIE:
J.BIRDSALL2

Registrations should be sent to:

James W. Birdsall
11112 NE 124 LN #D204
Kirkland, WA 98034

If you have an email address on any of the networks listed above, please
include it when registering, especially if you are requesting source code.
It is much easier to send the source code by email. Also, please specify
what sort of archive (ZIP, ZOO, ARC, LZH, ARJ, UNIX shar) you can handle
most easily.

6.1 ACKNOWLEDGEMENTS
--------------------

Thanks to Bob Parsons of Parsons Technology Inc. for some good suggestions
on the documentation and the C++ header file.


 December 13, 2017  Add comments

Leave a Reply