home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / itcnov90.arj / EMS.C next >
Encoding:
C/C++ Source or Header  |  1991-09-07  |  7.1 KB  |  223 lines

  1. /****************************************************************
  2. * EMS.C - simple EMS demonstration program                        *
  3. * Compile using "tcc -ml ems.c"                                    *
  4. ****************************************************************/
  5.  
  6. #include <stdio.h>        /* FILE, fileno(), NULL, printf()        */
  7. #include <dos.h>        /* REGS                                    */
  8. #include <stdlib.h>        /* exit()                                */
  9. #include <string.h>        /* strcpy()                                */
  10. #include <sys\types.h>    /* dev_t                                */
  11. #include <sys\stat.h>    /* fstat(), S_IFCHR, S_IFREG            */
  12. #include <assert.h>        /* assert()                                */
  13.  
  14. #define EMS_INT            (0x67)                /* EMS interrupt #    */
  15. #define TRUE            (1==1)                /* Boolean TRUE        */
  16. #define FALSE            (1==0)                /* Boolean FALSE    */
  17. #define PAGE_LEN        (16384)                /* Length of EMS pg    */
  18. #define MSG_LEN            (18)                /* Msg len (+EOS!)    */
  19. #define MSGS_PER_PAGE    (PAGE_LEN/MSG_LEN)    /* # msgs in page    */
  20. #define NUM_MESSAGES    (5000)                /* Number EMS msgs    */
  21.  
  22. void emsPrintError(int);
  23.  
  24. void main(void)
  25.     {
  26.     void *p0, *p1, *p2, *p3;    /* Pointers to physical pages    */
  27.     int   emsHandle;            /* Handle to allocated memory    */
  28.     FILE *tmp;                    /* scratch file handle            */
  29.     struct stat buffer;            /* buffer for fstat()            */
  30.     char (*msgBuf)[MSG_LEN];    /* ptr to array of "messages"    */
  31.     char  buff[25];                /* scratch buffer                */
  32.     int      i;                    /* scratch counter variable        */
  33.     union REGS emsRegs;            /* EMS communic. regs for int86    */
  34.     int   page, index;            /* Page & index for msg in EMS    */
  35.  
  36.     /*----- Ensure that far data pointers are the default ------*/
  37.     assert(sizeof(void far *)==sizeof(void *));
  38.  
  39.     /*------------- Determine if EMS is installed --------------*/
  40.     if ( (tmp=fopen("EMMXXXX0","rb")) == NULL)
  41.         {
  42.         puts("No EMS driver present");
  43.         fclose(tmp);
  44.         return;
  45.         }
  46.     fstat(fileno(tmp),&buffer);
  47.     if ( !(buffer.st_mode & S_IFCHR))
  48.         {
  49.         puts("No EMS driver present");
  50.         fclose(tmp);
  51.         return;
  52.         }
  53.  
  54.     /*------- Print the current status of the EMS driver -------*/
  55.     emsRegs.h.ah = 0x40;
  56.     int86(EMS_INT,&emsRegs,&emsRegs);
  57.     emsPrintError(emsRegs.h.ah);
  58.     if (emsRegs.h.ah)
  59.         return;
  60.  
  61.     /*--------- Print the version number of EMS driver ---------*/
  62.     emsRegs.h.ah=0x46;
  63.     int86(EMS_INT,&emsRegs,&emsRegs);
  64.     if (emsRegs.h.ah)
  65.         {
  66.         emsPrintError(emsRegs.h.ah);
  67.         return;
  68.         }
  69.     printf("EMS driver version = %c.%c\n",
  70.             (emsRegs.h.al>>4)   + '0',
  71.             (emsRegs.h.al&0x0f) + '0');
  72.     if (emsRegs.h.al < 0x32)
  73.         {
  74.         puts("Error - EMM is older than version 3.2!");
  75.         return;
  76.         }
  77.  
  78.     /*---- Print the page frame & physical window addresses ----*/
  79.     emsRegs.h.ah=0x41;
  80.     int86(EMS_INT,&emsRegs,&emsRegs);
  81.     if (emsRegs.h.ah)
  82.         {
  83.         emsPrintError(emsRegs.h.ah);
  84.         return;
  85.         }
  86.  
  87.     p0=MK_FP(emsRegs.x.bx,0x0000);    /* window 0 -> p0 = BX:0000 */
  88.     p1=MK_FP(emsRegs.x.bx,0x4000);    /* window 1 -> p1 = BX:4000    */
  89.     p2=MK_FP(emsRegs.x.bx,0x8000);    /* window 2 -> p2 = BX:8000    */
  90.     p3=MK_FP(emsRegs.x.bx,0xc000);    /* window 3 -> p3 = BX:C000    */
  91.  
  92.     printf("Page frame segment address = %04x\n",emsRegs.x.bx);
  93.     printf("Physical page 0 address = %p\n",p0);
  94.     printf("Physical page 1 address = %p\n",p1);
  95.     printf("Physical page 2 address = %p\n",p2);
  96.     printf("Physical page 3 address = %p\n",p3);
  97.  
  98.     /*----- Print # of unallocated pages and total # pages -----*/
  99.     emsRegs.h.ah=0x42;
  100.     int86(EMS_INT,&emsRegs,&emsRegs);
  101.     if (emsRegs.h.ah)
  102.         {
  103.         emsPrintError(emsRegs.h.ah);
  104.         return;
  105.         }
  106.     printf("Total EMS pages = %d\nUnused EMS pages= %d\n",
  107.                 emsRegs.x.dx,        emsRegs.x.bx);
  108.  
  109.     /*--------- Allocate some pages of expanded memory ---------*/
  110.     emsRegs.h.ah=0x43;
  111.     emsRegs.x.bx=(NUM_MESSAGES+MSGS_PER_PAGE)/MSGS_PER_PAGE;
  112.     int86(EMS_INT,&emsRegs,&emsRegs);
  113.     if (emsRegs.h.ah)
  114.         {
  115.         emsPrintError(emsRegs.h.ah);
  116.         return;
  117.         }
  118.     printf("Allocated %d pages to handle %d\n",
  119.             emsRegs.x.bx,        emsRegs.x.dx);
  120.     emsHandle = emsRegs.x.dx;
  121.  
  122.     /*----------------- Load EMS RAM with data -----------------*/
  123.     msgBuf = p0;        /* Set msgBuf array to physical page 0    */
  124.     for (i=0; i<NUM_MESSAGES; i++)
  125.         {
  126.         sprintf(buff,"EMS message #%04d",i);
  127.         if ( (i%100) == 0 ) fputc('.',stdout);
  128.  
  129.         page  = i / MSGS_PER_PAGE;
  130.         index = i % MSGS_PER_PAGE;
  131.  
  132.         /*--- Map indicated logical page into physical page 0 --*/
  133.         emsRegs.h.ah = 0x44;                /* Map EMS page cmd    */
  134.         emsRegs.x.bx = page;                /* Logical page        */
  135.         emsRegs.h.al = 0;                    /* Physical page 0    */
  136.         emsRegs.x.dx = emsHandle;            /* EMS RAM handle    */
  137.         int86(EMS_INT,&emsRegs,&emsRegs);
  138.         if (emsRegs.h.ah)
  139.             {
  140.             emsPrintError(emsRegs.h.ah);    /* print error msg    */
  141.             i=NUM_MESSAGES;                    /* quit loop        */
  142.             continue;                        /* skip the strcpy    */
  143.             }
  144.  
  145.         /*- Copy the message into the appropriate EMS RAM slot -*/
  146.         strcpy(msgBuf[index],buff);
  147.         }
  148.     fputc('\n',stdout);
  149.  
  150.     /*--- Allow the user to access any message in the buffer ---*/
  151.     msgBuf = p3;        /* Set msgBuf array to physical page 3    */
  152.     do    {
  153.         printf("\nEnter message # to retrieve, or -1 to quit:");
  154.         gets(buff);
  155.         sscanf(buff,"%d",&i);
  156.         if ( (i>=0) && (i<NUM_MESSAGES) )
  157.             {
  158.             page  = i / MSGS_PER_PAGE;
  159.             index = i % MSGS_PER_PAGE;
  160.  
  161.             /*----- Map indicated page into physical page 3 ----*/
  162.             emsRegs.h.ah = 0x44;            /* Map EMS page cmd    */
  163.             emsRegs.x.bx = page;            /* Logical page        */
  164.             emsRegs.h.al = 3;                /* Physical page 3    */
  165.             emsRegs.x.dx = emsHandle;        /* EMS RAM handle    */
  166.             int86(EMS_INT,&emsRegs,&emsRegs);
  167.             if (emsRegs.h.ah)
  168.                 {
  169.                 emsPrintError(emsRegs.h.ah);/* print error msg    */
  170.                 i = -1;                        /* quit loop        */
  171.                 continue;                    /* skip the strcpy    */
  172.                 }
  173.  
  174.             /*----------- Print the indicated message ----------*/
  175.             printf("Page=%d, Index=%d, msg=%s\n",
  176.                       page,       index,    msgBuf+index);
  177.             }
  178.         } while (i != -1);
  179.  
  180.     /*----------- Free the EMS RAM back to EMS driver ----------*/
  181.     emsRegs.h.ah=0x45;
  182.     emsRegs.x.dx=emsHandle;
  183.     int86(EMS_INT,&emsRegs,&emsRegs);
  184.     if (emsRegs.h.ah)
  185.         {
  186.         emsPrintError(emsRegs.h.ah);        /* Print error msg    */
  187.         return;
  188.         }
  189.     printf("Released all memory for handle %d\n",emsRegs.x.dx);
  190.     }
  191.  
  192. /****************************************************************
  193. * emsPrintError - print error message for value in AH            *
  194. *                                                                *
  195. * INP:    emsRegs - register set (AH holds status code)            *
  196. ****************************************************************/
  197. void emsPrintError(int status)
  198.     {
  199.     char *s;
  200.     switch (status)
  201.         {
  202.         case 0x00:    s="Ok";                                break;
  203.         case 0x80:    s="driver malfunction";                break;
  204.         case 0x81:    s="hardware malfunction";            break;
  205.         case 0x83:    s="bad handle";                        break;
  206.         case 0x84:    s="undefined function";                break;
  207.         case 0x85:    s="no free handles";                break;
  208.         case 0x86:    s="page map context error";            break;
  209.         case 0x87:    s="insufficient memory pages";        break;
  210.         case 0x88:    s="Not enough free pages";            break;
  211.         case 0x89:    s="Can't allocate zero (0) pages";    break;
  212.         case 0x8a:    s="Logical page out of range";        break;
  213.         case 0x8b:    s="Physical page out of range";        break;
  214.         case 0x8c:    s="Page map hardware RAM full";        break;
  215.         case 0x8d:    s="Page map already has a handle";    break;
  216.         case 0x8e:    s="Page map not mapped to handle";    break;
  217.         case 0x8f:    s="Undefined subfunction number";    break;
  218.         default:    printf("EMS: unknown status=%02x",status);
  219.                     return;
  220.         }
  221.     printf("EMS: %s\n",s);
  222.     }
  223.