EMS.H.TXT

===============================================================================
     Date: 11-14-95    Time: 03:43p     Number: 1133   
     From: Cliff Rhodes                  Refer:         
       To: Stanley Barker             Board ID: FIX             Reply: 
  Subject: Memory EMS/ 1 of 3              132: fido.en.c_ec   Status: Public 
-------------------------------------------------------------------------------
--> STANLEY BARKER wrote to ALL  <--

SB>                       I program in Turbo C/C++ 3.0 for DOS.
SB>                I was wondering if anybody has any source code or
SB>                examples to work with the EMS manger.

OK:

/*  EMS.H
 *
 * Header file Expanded Memory Routines
 *
 */

#ifndef EMS_H_
#define EMS_H_

#define EMS_PAGE_SIZE   16384   /* Each page is this size */

unsigned int EMSbaseaddress(void);
int  EMSversion(void);
int  EMSstatus(void);
int  EMSpages(void);
int  EMSalloc(int pages);
int  EMSfree(int handle);
int  EMSmap(int bank, int handle, int page);

#endif
___
 * CMPQwk 1.4 #1692 * "When I want to read a book I write one." - Benjamin
Disrae

--- Maximus/2 3.00
 * Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================
     Date: 11-14-95    Time: 03:44p     Number: 1134   
     From: Cliff Rhodes                  Refer:         
       To: Stanley Barker             Board ID: FIX             Reply: 
  Subject: Memory EMS/ 2 of 3              132: fido.en.c_ec   Status: Public 
-------------------------------------------------------------------------------
/* EMS.C
 *
 * Expanded Memory Functions
 *
 */

#include 
#include 

#include "ems.h"

/* EMS driver values */
#define EMS_ID      "EMMXXXX0" /* EMS identifier string */
#define EMS_INT     0x67       /* EMS interrupt number */
#define EMS_VERSION 0x32       /* Version 3.2 of EMS */

/* EMS service codes */
#define EMSservice1  0x40    /* Get EMS status */
#define EMSservice2  0x41    /* Get segment address of page 0 */
#define EMSservice3  0x42    /* Get total number of expanded pages */
#define EMSservice4  0x43    /* Get handle and assign pages to it */
#define EMSservice5  0x44    /* Map a page into one of the page frames */
#define EMSservice6  0x45    /* Close EMS handle */
#define EMSservice7  0x46    /* Get the EMS version number */

unsigned int EMSbaseaddress(void)
{
  /* Determines if EMS present. If so returns base segment of EMS.
   * Returns 0 if EMS not available. The base segment is necessary
   * for mapping EMS memory pages into the user address space (see
   * EMSmap() below).
   */

  static const char tag[] = EMS_ID;

  char far      *p;
  int           i;
  union REGS    regs;
  struct SREGS  segs;

  regs.h.ah = 0x35;
  regs.h.al = EMS_INT;
  int86x(0x21, ®s, ®s, &segs);

  p = (char far *) (MK_FP(segs.es, 10)); /* EMS_ID must be at offset 10 */

  for(i = 0; i < 8; i++)
     if(tag[i] != p[i])
         return 0;                       /* If EMS_ID not found, return */

  regs.h.ah = EMSservice2;               /* Get page frame segment */
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? 0 : (unsigned int) regs.x.bx;
}

int EMSversion(void)
{
  /* Returns current EMS version, -1 if not found or obsolete */

  union REGS regs;

  regs.h.ah = EMSservice7;
  int86(EMS_INT, ®s, ®s);

  if(!regs.h.ah && regs.h.al >= EMS_VERSION)  /* Make sure at least 3.2 */
     return regs.x.ax;

  return -1;
}

int  EMSstatus(void)
{
  /* Returns 0 if EMS system OK, -1 if not  */

  union REGS regs;

  regs.h.ah = EMSservice1;
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? -1 : 0;
}

int EMSpages(void)
{
  /* Returns number of free EMS pages (each page is 16k), -1 if error */

  union REGS  regs;

  regs.h.ah = EMSservice3;
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? -1 : (int) regs.x.bx;
}

int EMSalloc(int pages)
{
  /* Returns handle to block of size pages or -1 if error.
   * NOTE: always free any handles when you are done!.
   */

  union REGS regs;

  regs.h.ah = EMSservice4;
  regs.x.bx = pages;
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? -1 : (int) regs.x.dx;
}

int EMSfree(int handle)
{
  /* Frees handle block, returns 0 if successful, -1 if error */

  union REGS regs;

  regs.h.ah = EMSservice6;
  regs.x.dx = handle;
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? -1 : 0;
}

int  EMSmap(int bank, int handle, int page)
{
  /* Maps page of handle into bank. Returns 0 if successful, -1 if error.
   * Each handle controls 1 or more 16k pages of EMS memory.
   * There are four banks 0-3. bank 0 starts at the segment returned by
   * EMSbaseaddress(), bank 1 starts at that segment with offset 16k, etc.
   */

  union REGS regs;

  regs.h.ah = EMSservice5;
  regs.h.al = bank;
  regs.x.bx = page;
  regs.x.dx = handle;
  int86(EMS_INT, ®s, ®s);

  return regs.h.ah ? -1 : 0;
}
___
 * CMPQwk 1.4 #1692 * The gene pool has no lifeguard

--- Maximus/2 3.00
 * Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================
     Date: 11-14-95    Time: 03:45p     Number: 1135   
     From: Cliff Rhodes                  Refer:         
       To: Stanley Barker             Board ID: FIX             Reply: 
  Subject: Memory EMS/ 3 of 3              132: fido.en.c_ec   Status: Public 
-------------------------------------------------------------------------------
/* EMSTEST.C
 *
 * Test EMS functions found in ems.c
 *
 */

#include 
#include 

#include "ems.h"

int main(void)
{
  const char str[] = "This is just a test string!";
  int i, ver, handle1, handle2;
  unsigned int baseaddress;
  char far *cp;

  /* Get the segment for mapping expanded memory into address space */
  if((baseaddress = EMSbaseaddress()) == 0)
  {
     printf("Expanded memory manager not found, terminating program.\n");
     return 1;
  }

  /* Get the version number an the number of pages available */
  ver = EMSversion();
  printf("EMM Version %d.%d loaded\n", ver >> 4, ver & 0x0f);
  printf("There are %d pages available\n", EMSpages());

  /* Allocate a few pages */
  handle1 = EMSalloc(3);   /* Allocate 3 pages */
  if(handle1 < 0)
  {
     printf("EMM allocation failed on handle 1\n");
     return 1;
  }
  handle2 = EMSalloc(1);   /* Allocate 1 page */
  if(handle2 < 0)
  {
     EMSfree(handle1);
     printf("EMM allocation failed on handle 2\n");
     return 1;
  }
  printf("There are %d pages available after allocating 4\n", EMSpages());

  /* Map the allocated pages into the address space */
  if(EMSmap(0, handle1, 1) < 0)            /* Mapped page 1 into bank 0 */
     printf("Error mapping handle 1\n");
  if(EMSmap(3, handle2, 0) < 0)            /* Mapped page 0 into bank 3 */
     printf("Error mapping handle 2\n");
  else
  {
     /* Write test string into beginning of handle2 */
     cp = (char far *) (MK_FP(baseaddress, 3 * EMS_PAGE_SIZE));
     for(i = 0; str[i]; i++)
        cp[i] = str[i];
     cp[i] = '\0';

     /* Read back test string and look for a match */
     cp = (char far *) (MK_FP(baseaddress, 3 * EMS_PAGE_SIZE));
     for(i = 0; str[i]; i++)
        if(cp[i] != str[i])
        {
           printf("Data mismatch at character %d\n", i);
           break;
        }
  }
  EMSfree(handle1);
  EMSfree(handle2);

  return 0;
}
___
 * CMPQwk 1.4 #1692 * "Is sex dirty? Only if it's done right." - Woody Allen

--- Maximus/2 3.00
 * Origin: COMM Port OS/2 (713) 980-9671 (1:106/2000)
===============================================================================