Dec 192017
 
C++ Class for transparent array access to EMS memory, shareware version limited to 1Mb memory.
File EMSCL1.ZIP from The Programmer’s Corner in
Category C++ Source Code
C++ Class for transparent array access to EMS memory, shareware version limited to 1Mb memory.
File Name File Size Zip Size Zip Type
EMSCLASS.DOC 14584 4786 deflated
EMSCLASS.HPP 5564 1853 deflated
EMSCL_TL.LIB 18144 7660 deflated
MAIN_EMS.CPP 3099 1352 deflated
ORDER.DOC 855 312 deflated
TEST_EMS.CPP 8549 2360 deflated

Download File EMSCL1.ZIP Here

Contents of the EMSCLASS.DOC file



EMS CLASS Version 1.3 (1/17/94) Documentation
Copyright (c) 1993,1994 by Scott L. Diorio
All Right Reserved.

I. Introduction
----------------

The EMS Class is a C++ class allowing transparent access to your PCs expanded
memory from DOS. The programmer does not have to understand EMS in order to
use this class. If you have used a char buffer created with new or alloc then you
can use the EMS class within a few minutes.

The EMS class is shareware. The shareware version allows access up to one megabyte
or 1,024,000 bytes of expanded memory. This should be enough to evaluate the software.
With 1 meg you can load and manipulate a 24 bit 640x480 picture file with bytes to
spare. If you want to have access to all your machines expanded memory then you need
the registered version.
=========================================================================

Files Included
---------------

EMSCL_TL.LIB - Turbo C Large Model library for the EMS class
EMSCLASS.HPP - EMS class header file
EMSCLASS.DOC - This file
ORDER.DOC - Order form
MAIN_EMS.CPP - A file with usage examples
TEST_EMS.CPP - Comprehensive test case for the class
=========================================================================

Hardware requirements:
-----------------------

To run the EMS class, you MUST have:
1) A PC with DOS
2) At least a '286
3) Expanded memory

=========================================================================

Software Requirements
----------------------

The EMS class was written with Turbo C++. The Microsoft C/C++ version will
be available next.

The large model library is included in the shareware version

=========================================================================

Example Usage: (this is enough to get you started)
-------------------------------------------------

#include "emsclass.hpp"

EmsKernel EMS; // Globally declare Kernel object

void main(void)
{
EMS.Alloc(50); // Alloc 50-16K pages of EMS memory or 819,200 bytes
// to the EMS kernel.
EMSbuf A[500000]; // declare a buffer of 500,000
memset(A,0,500000); // set buffer to all 0's
memset(A+10500,255,400000); // set 400,000 characters in buffer to 255
// starting from offset 10,500 in the buffer
for(long t=0;t<500000;t++) // step through buffer one character at a time
{
A[t]=A[t]+1;
}
}
=========================================================================

Registering the Product
-----------------------

When you register, you will be sent a disk with the latest version of the EMS class
and the source code. Once you register, you will be able to get any future versions for
a small shipping fee.

To obtain a registered version send $20 to:

Scott L. Diorio
P.O. Box 8186
Fresno, CA 93747


I welcome any comments, suggestions, questions, etc. Please feel free to contact me.

Where I can be reached:

Phone: (209)452-8875 (Pacific Time)
Compuserve: 72717,363
America Online: Tritum

=========================================================================

Licencing Agreement/Legal Stuff
--------------------------------

The EMS CLASS is not in the public domain. All the files are Copyright 1993,
1994 by Scott L. Diorio, all rights reserved. Permission is granted to do the
following:

You have 30 days to evaluate the product. If you want to use the product past 30
days you must obtain a registered version.

This software may NOT be included in whole or in part in any software libraries to
be sold or distributed in any way without prior permission from the author.

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

If you register the EMS Class, you may distribute and sell any executable which
results from using its code in your applications. You may NOT include any
SOURCE code of this software with anything sold, distributed or printed.

The contents of the distribution archive, and all other related files, information,
and services are provided "as is" and without warranty. To the extent permitted
by applicable law, the author disclaims all warranties, express or implied, including
but not limited to, any implied warranty of merchantability or fitness for a particular
purpose. While effort has been made to ensure that the files, information, and
services are accurate and correct, the author shall not be liable for damages arising
out of the use of or inability to use this product, including but not limited to, loss
of profit, data, or use of this software, or special, incidental, or consequential damages
or other similar claims, even if the author has been specifically advised of the
possibility of such damages. Some states do not allow the exclusion of incidental or consequential damages, so the foregoing limitation may not apply to you.


=========================================================================

History
-------

Have you ever downloaded a piece of software that looked great only to find out
that it's nearly impossible to use? There is alot great software out there, but alot
of it is too difficult to use. One great aspect of OOP programming is hiding the
complexity of the design from the end user. It should be a no-brainer to use. That's
how I've designed the EMS class. If you have worked with character buffers, then you
already know how to use it. Plain and simple. No 50 pages of documentation or
endless tutorial that leaves you with a blank stare on your face. Just plug and play.

=========================================================================

Usage:
------

The EMS class is used by first declaring the EmsKernel object globally. You may
then declare up to 32000 EMSbuf objects. In this version, only 1 EMSbuf object may
be declared for each 16K page of EMS memory. I am looking into the possiblity of
having multiple objects per 16K page in the next version.


Some Considerations:

Make sure to dereference when working with an EMSbuf variable that was created with
the new operator. For example:

EMSbuf *A;
A=new EMSbuf(100000);
memset(A,0,100000); // ERROR !
memset(*A,0,100000); // Correct
A[50]='*'; // ERROR !
(*A)[50]='*'; // Correct
delete(A);

Kernel Functions
--------------

EmsKernel(int debug, int errlevel);

Constructor, Must be called Globally. The default constructor needs no argument. A
special debugging option is available. If the constructor is passed a 1 (or ON) for
debug then a special disk file is created. This file allows for the freeing of EMS
memory after a program was interrupted. For example, when debugging, you may
halt your program serveral times. Each time the global EmsKernel is created, it
allocates a amount of EMS memory. If the program does not run to completion,
then the global EmsKernel object never goes out of scope and thus never frees that
EMS memory. The special file allows you to go through your debugging cycle without
continually losing EMS memory.

errlevel settings
0 - Set internal Error variable (default)
1 - 0 + report Errors to cerr
2 - 0,1 + pauses for keypress
3 - 0,1,2 + terminate process

Returns: n/a
------------------------------------------------------------------------

int Alloc(int);

Use this function to tell the system how many 16K pages you want to
allocate the the EmsKernel

Returns: 0 on success, -1 on Error
------------------------------------------------------------------------

int SystemPagesFree(void)

Get free system pages

Returns: the number of free 16K EMS pages available to your system.
------------------------------------------------------------------------

int AppPagesFree(void)

Get free EmsKernel pages

Returns: the number of free 16K EMS pages available to the EmsKernel
------------------------------------------------------------------------

void DumpMap(void)

Display a map of all EMS pages allocated by the EmsKernel.

Returns: nothing
-----------------------------------------------------------------------

void DumpHandles(void)

Display which EMS blocks are allocted to which handle or EMSbuf

Returns: nothing
-----------------------------------------------------------------------

void DumpAll(void)

Calls DumpMap() and DumpHandles() in succession.

Returns: nothing
-----------------------------------------------------------------------

EMSbuf Functions
================

EMSbuf(unsigned long size)

Constructor. Creates an EMSbuf of size bytes.

Returns: nothing

------------------------------------------------------------------------

unsigned long Size(void)

Get buffer size

Returns: Size of EMSbuf buffer

------------------------------------------------------------------------

void long Resize(void)

Resizes an EMSbuf buffer

Returns: Nothing
------------------------------------------------------------------------

char& operator [](unsigned long offset)

Returns a character 'offset' bytes into the EMSbuf.

Returns: Reference to char
------------------------------------------------------------------------

EMSbuf& operator+(unsigned long offset)

Returns a reference to a EMSbuf that starts at 'offset' bytes into the
affected buffer.

Returns: Reference to object
------------------------------------------------------------------------

Friend Functions
--------------

Each of the functions below work exactly like their original counterparts that are used for character buffers.

------------------------------------------------------------------------

EMSbuf& memset(EMSbuf &, int, unsigned long);

Set a range in an EMSbuf to a value;

Example:

EMSbuf A(100000);
memset(A,0,50000);

Returns: Reference to object
------------------------------------------------------------------------

EMSbuf& memcpy(EMSbuf &, void *, size_t);

Copy up to 65532 characters from a memory location pointed to by a void *
to an EMSbuf object.

Example:

EMSbuf A(100000);
char tmp[2000];
memcpy(A,tmp,2000);

Returns: Reference to object
------------------------------------------------------------------------

void * memcpy(void *, EMSbuf &, size_t);

Copy up to 65532 characters from a EMS object to a memory location pointed
to by a void *

Example:

EMSbuf A(100000);
char tmp[2000];
memcpy(tmp,A,2000);

Returns: void *
------------------------------------------------------------------------

int memcpy(EMSbuf &, EMSbuf &, unsigned long);

Copy up to 4,294,967,295 bytes from one EMSbuf to another.

Example:

EMSbuf s1(512000);
EMSbuf s2(512000);
memcpy(s2,s1,250000);

Returns: Reference to object
------------------------------------------------------------------------

int memcmp(EMSbuf &s1, void *s2, unsigned);

Compare up to 65532 bytes from in EMSbuf s1 and void *s2

Example:
EMSbuf s1(512000);
void *s2;
memcmp(s1,s2,32768);

Returns: 0 - if buffers are equivilant
<0 - if s1 >0 - if s1>s2
------------------------------------------------------------------------

int memcmp(void *s1, EMSbuf &s2, unsigned);

Compare up to 65532 bytes from in void *s1 and EMSbuf *s2

Example:
void *s1;
EMSbuf s2(512000);
memcmp(s1,s2,32768);

Returns: 0 - if buffers are equivilant
<0 - if s1 >0 - if s1>s2
------------------------------------------------------------------------

EMSbuf& memcmp(EMSbuf &s1, EMSbuf &s2, unsigned long);

Compare up to 4,294,967,295 bytes from in two EMSbuf objects

Example:
EMSbuf A(512000);
EMSbuf B(512000);
memcmp(B,A,250000);

Returns: 0 - if buffers are equivilant
<0 - if s1 >0 - if s1>s2
=========================================================================

How it works - tech stuff
----------------------

The EmsKernel object maintains a list of EMSbuf objects. Even though the EMSbuf
is a descendant of EmsKernel, the Kernels data is only duplicated once because all
the data is declared static in the Kernel.

The biggest problem with Expanded memory is that it is broken up into a series of
16k pages. Only four of these pages can be 'mapped' to the system at one time. So
when you want to access 512K of expanded memory, you have to access it 16K at a
time in grouped chunks of 64K. It is easy to see why someone would want to stay
away from using it. It makes your program code complicated and confusing.

Accessing a page of Expanded memory is just as fast as accessing a regular buffer
declared using the heap. The time differencial comes when remapping takes place.
The EmsKernel maintains a statistical breakdown of the most recently used EMSbuf
objects. This limits the remapping to a minimum and allows the fastest access to
multiple expanded memory pages possible.

When accessing an EMSbuf one character at a time with the [] operator, there is speed
consideration. Since only 4 16K pages can be mapped at a time, only 4 EMSbuf objects
can be mapped at a time. For example, if 4 EMSbuf objects are all being used inside a
loop then no extra remapping has to take place. When 5 or more EMSbuf variables are
present, remapping must take place each time a variable is accessed. So if you have
a range of characters to move, you are better off using the special memcpy supplied.

When working with EMSbuf objects and character buffers, the size of the character
buffers is limited to 65532 characters. Trying to access beyond 65532 characters
has caused crashes under some compilers. Currently, the EMSbuf class disallows
access past the 65532nd character to avoid problems. Since this class is for working
with EMS this limitation shouldn't be a problem.

=========================================================================

Bugs/Updates
-----------

Several bugs from previous versions have been corrected. I thank everyone for their
input, it proved invaluable. As before, if any bugs come up, please let me know and
I will attempt to fix them as soon as they are reported.




 December 19, 2017  Add comments

Leave a Reply