===============================================================================
Date: 11-18-95 Time: 04:52p Number: 1353
From: Cliff Rhodes Refer: 1287
To: Kieran Haughey Board ID: FIX Reply:
Subject: XMS 1 of 3 132: fido.en.c_ec Status: Public
-------------------------------------------------------------------------------
--> Kieran Haughey wrote to All <--
KH>I was wondering if anyone might be able to help me here.. I
KH>want to access the EMS or XMS in my computer, and I was
KH>wondering if someone might be able to provide me with some
KH>source code, or an explaination of how to do it...
Kieran, I just posted some EMS routines about 3 days ago. If you didn't see
them, let me know and I'll repost. Here are some XMS routines:
/* XMS.H
*
* Header file for Extended Memory routines in XMS.C.
*
*/
#ifndef _XMS_H
#define _XMS_H
int XMSinit(void);
int XMSversion(void);
long XMScoreleft(void);
unsigned int XMSalloc(long size);
int XMSfree(unsigned int handle);
long XMSmemcpy(unsigned int desthandle, long destoff,
unsigned int srchandle, long srcoff, long n);
int DOStoXMSmove(unsigned int desthandle, long destoff,
const char *src, int n);
int XMStoDOSmove(char *dest, unsigned int srchandle, long srcoff, int n);
#endif
___
* CMPQwk 1.4 #1692 * "The knowledge of sin is the start of salvation." -
Epicuru
--- Maximus/2 3.00
* Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================
Date: 11-18-95 Time: 04:55p Number: 1354
From: Cliff Rhodes Refer: 1287
To: Kieran Haughey Board ID: FIX Reply:
Subject: XMS 2 of 3 132: fido.en.c_ec Status: Public
-------------------------------------------------------------------------------
/* XMS.C
*
* Routines to use Extended Memory from a DOS program.
* NOTE1: Code has only been tested on a Borland Compiler.
* NOTE2: Uses inline assembly language--so other compilers beware!
*
* Released to the public domain by Cliff Rhodes with no guarantees
* of any kind.
*
*/
#include
#include "xms.h"
#define XMS_INT 0x002f /* DOS Multiplex interrupt */
static int (_far * XMSDriver)(void);
static int initflag = 0;
static int XMSDriverCall(void)
{
/* This just checks to insure that we've been initialized. */
if(initflag) /* If XMSinit() has been successful */
return XMSDriver();
else
return 0;
}
int XMSinit(void)
{
/* Verify that an Extended Memory Manager is installed.
* Returns 1 if manager found, 0 if not.
* NOTE: This function should be called before any other XMS function!
*/
union REGS regs;
struct SREGS sregs;
regs.x.ax = 0x4300; /* Verify XMS manager present */
int86(XMS_INT, ®s, ®s);
if(regs.h.al == 0)
return 0;
regs.x.ax = 0x4310; /* Get XMS manager entry point */
int86x(XMS_INT, ®s, ®s, &sregs);
XMSDriver = MK_FP(sregs.es, regs.x.bx); /* Save entry point */
return (initflag = 1);
}
int XMSversion(void)
{
/* Return version number of XMS driver. */
_asm mov ax, 0
return XMSDriverCall();
}
long XMScoreleft(void)
{
/* Returns number of bytes available in largest free block. */
_asm mov ax, 0x0800
return 1024L * (long) XMSDriverCall();
}
unsigned int XMSalloc(long size)
{
/* Attempts to allocate size bytes of extended memory.
* Returns handle if successful, 0 if not.
* NOTE: Actual size allocated will be the smallest multiple of 1024
* that is larger than size.
*/
/* Get the number of 1024 byte units required by size. */
int rval = (int) (size / 1024L);
if(size % 1024L)
rval++; /* Add a block for any excess */
_asm {
mov dx, rval
mov ax, 0x0900
}
if(XMSDriverCall())
_asm mov rval, dx
else
rval = 0;
return rval;
}
int XMSfree(unsigned int handle)
{
/* Attempts to free extended memory referred to by handle. Returns 1
* if successful, 0 if not.
*/
_asm {
mov dx, handle
mov ax, 0x0a00
}
return XMSDriverCall();
}
typedef struct {
long nbytes; /* Number of bytes to move */
unsigned int shandle; /* Handle of source memory */
long soffset; /* Offset of source in handle's memory area */
unsigned int dhandle; /* Handle of destination memory */
long doffset; /* Offset of destination in memory */
} XMSRequestBlock;
static XMSRequestBlock bd;
static long XMS_Move(long n)
{
long rval;
unsigned int segm, offs;
XMSRequestBlock _far *fptr = (XMSRequestBlock _far *) &bd;
bd.nbytes = n;
offs = FP_OFF(fptr);
segm = FP_SEG(fptr);
_asm {
push ds /* Save DS */
mov ds, segm
mov si, offs
mov ax, 0x0b00
}
rval = (XMSDriverCall() == 0) ? 0L : n;
_asm pop ds /* Restore DS since we changed it to make this call */
return rval;
}
long XMSmemcpy(unsigned int desthandle, long destoff,
unsigned int srchandle, long srcoff, long n)
{
/* Attempts to copy n bytes from srchandle to desthandle memory areas.
* Returns number of bytes copied, or 0 on error.
*/
bd.shandle = srchandle;
bd.soffset = srcoff;
bd.dhandle = desthandle;
bd.doffset = destoff;
return XMS_Move(n);
}
int DOStoXMSmove(unsigned int desthandle, long destoff,
const char *src, int n)
{
/* Attempts to copy n bytes from DOS src buffer to desthandle memory area.
* Returns number of bytes copied, or 0 on error.
*/
bd.shandle = 0;
bd.soffset = (long) ((char _far *) src);
bd.dhandle = desthandle;
bd.doffset = destoff;
return (int) XMS_Move((long) n);
}
int XMStoDOSmove(char *dest, unsigned int srchandle, long srcoff, int n)
{
/* Attempts to copy n bytes to DOS dest buffer from srchandle memory area.
* Returns number of bytes copied, or 0 on error.
*/
bd.shandle = srchandle;
bd.soffset = srcoff;
bd.dhandle = 0;
bd.doffset = (long) ((char _far *) dest);
return (int) XMS_Move((long) n);
}
___
* CMPQwk 1.4 #1692 * "Time is the best medicine." - Ovid
--- Maximus/2 3.00
* Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================
Date: 11-18-95 Time: 04:56p Number: 1355
From: Cliff Rhodes Refer: 1287
To: Kieran Haughey Board ID: FIX Reply:
Subject: XMS 3 of 3 132: fido.en.c_ec Status: Public
-------------------------------------------------------------------------------
/* XMSTEST.C
*
* Test extended memory routines in file XMS.C
*
*/
#include
#include
#include "xms.h"
#define BufSize 30000
#define BlockSize (long) 130000L
int main(void)
{
int i;
unsigned int handle1, handle2; /* XMS handles */
char *buf1, *buf2;
if((i = XMSinit()) == 0)
{
printf("Extended Memory Manager not found, terminating program\n");
return 1;
}
i = XMSversion();
printf("Extended Memory Manager Version %d.%d is installed\n",
i >> 8, (i & 0xff));
printf("There are %ld extended memory bytes available\n", XMScoreleft());
buf1 = malloc(BufSize);
buf2 = malloc(BufSize);
if(buf1 == NULL || buf2 == NULL)
{
printf("Error allocating conventional memory\n");
return 1;
}
for(i = 0; i < BufSize; i++) /* Fill buf1 with some values */
{
buf1[i] = i % 255;
buf2[i] = 0;
}
handle1 = XMSalloc(BlockSize);
if(handle1 == 0)
{
printf("Error allocating XMS memory for handle 1\n");
return 1;
}
printf("Handle 1 is %u and represents %ld bytes\n", handle1, BlockSize);
printf("There are %ld extended memory bytes available\n", XMScoreleft());
handle2 = XMSalloc(BlockSize);
if(handle2 == 0)
{
XMSfree(handle1);
printf("Error allocating XMS memory for handle 2\n");
return 1;
}
printf("Handle 2 is %u and represents %ld bytes\n", handle2, BlockSize);
printf("There are %ld extended memory bytes available\n", XMScoreleft());
/* Copy data from DOS buf1 to XMS memory of handle1 */
if(DOStoXMSmove(handle1, 0L, buf1, (long) BufSize) != BufSize)
printf("DOStoXMS copy failed\n");
/* Copy XMS handle1 data to XMS handle2 */
if(XMSmemcpy(handle2, 0L, handle1, 0L, BlockSize) != BlockSize)
printf("XMS copy failed\n");
/* Copy XMS handle2 data to DOS buf2 */
if(XMStoDOSmove(buf2, handle1, 0L, (long) BufSize) != BufSize)
printf("XMStoDOS copy failed\n");
/* buf1 data should now == buf2 data */
for(i = 0; i < BufSize; i++)
{
if(buf1[i] != buf2[i])
{
printf("*** ERROR: Mismatch in DOS buffers at location %d ***\n",
i);
break;
}
}
free(buf1);
free(buf2);
XMSfree(handle2);
printf("There are %ld bytes available after freeing handle 2\n",
XMScoreleft());
XMSfree(handle1);
printf("There are %ld bytes available after freeing handle 1\n",
XMScoreleft());
return 0;
}
___
* CMPQwk 1.4 #1692 * "I would sooner fail than not be among the greatest." -
Joh
--- Maximus/2 3.00
* Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================