home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * EMS.C - simple EMS demonstration program *
- * Compile using "tcc -ml ems.c" *
- ****************************************************************/
-
- #include <stdio.h> /* FILE, fileno(), NULL, printf() */
- #include <dos.h> /* REGS */
- #include <stdlib.h> /* exit() */
- #include <string.h> /* strcpy() */
- #include <sys\types.h> /* dev_t */
- #include <sys\stat.h> /* fstat(), S_IFCHR, S_IFREG */
- #include <assert.h> /* assert() */
-
- #define EMS_INT (0x67) /* EMS interrupt # */
- #define TRUE (1==1) /* Boolean TRUE */
- #define FALSE (1==0) /* Boolean FALSE */
- #define PAGE_LEN (16384) /* Length of EMS pg */
- #define MSG_LEN (18) /* Msg len (+EOS!) */
- #define MSGS_PER_PAGE (PAGE_LEN/MSG_LEN) /* # msgs in page */
- #define NUM_MESSAGES (5000) /* Number EMS msgs */
-
- void emsPrintError(int);
-
- void main(void)
- {
- void *p0, *p1, *p2, *p3; /* Pointers to physical pages */
- int emsHandle; /* Handle to allocated memory */
- FILE *tmp; /* scratch file handle */
- struct stat buffer; /* buffer for fstat() */
- char (*msgBuf)[MSG_LEN]; /* ptr to array of "messages" */
- char buff[25]; /* scratch buffer */
- int i; /* scratch counter variable */
- union REGS emsRegs; /* EMS communic. regs for int86 */
- int page, index; /* Page & index for msg in EMS */
-
- /*----- Ensure that far data pointers are the default ------*/
- assert(sizeof(void far *)==sizeof(void *));
-
- /*------------- Determine if EMS is installed --------------*/
- if ( (tmp=fopen("EMMXXXX0","rb")) == NULL)
- {
- puts("No EMS driver present");
- fclose(tmp);
- return;
- }
- fstat(fileno(tmp),&buffer);
- if ( !(buffer.st_mode & S_IFCHR))
- {
- puts("No EMS driver present");
- fclose(tmp);
- return;
- }
-
- /*------- Print the current status of the EMS driver -------*/
- emsRegs.h.ah = 0x40;
- int86(EMS_INT,&emsRegs,&emsRegs);
- emsPrintError(emsRegs.h.ah);
- if (emsRegs.h.ah)
- return;
-
- /*--------- Print the version number of EMS driver ---------*/
- emsRegs.h.ah=0x46;
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah);
- return;
- }
- printf("EMS driver version = %c.%c\n",
- (emsRegs.h.al>>4) + '0',
- (emsRegs.h.al&0x0f) + '0');
- if (emsRegs.h.al < 0x32)
- {
- puts("Error - EMM is older than version 3.2!");
- return;
- }
-
- /*---- Print the page frame & physical window addresses ----*/
- emsRegs.h.ah=0x41;
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah);
- return;
- }
-
- p0=MK_FP(emsRegs.x.bx,0x0000); /* window 0 -> p0 = BX:0000 */
- p1=MK_FP(emsRegs.x.bx,0x4000); /* window 1 -> p1 = BX:4000 */
- p2=MK_FP(emsRegs.x.bx,0x8000); /* window 2 -> p2 = BX:8000 */
- p3=MK_FP(emsRegs.x.bx,0xc000); /* window 3 -> p3 = BX:C000 */
-
- printf("Page frame segment address = %04x\n",emsRegs.x.bx);
- printf("Physical page 0 address = %p\n",p0);
- printf("Physical page 1 address = %p\n",p1);
- printf("Physical page 2 address = %p\n",p2);
- printf("Physical page 3 address = %p\n",p3);
-
- /*----- Print # of unallocated pages and total # pages -----*/
- emsRegs.h.ah=0x42;
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah);
- return;
- }
- printf("Total EMS pages = %d\nUnused EMS pages= %d\n",
- emsRegs.x.dx, emsRegs.x.bx);
-
- /*--------- Allocate some pages of expanded memory ---------*/
- emsRegs.h.ah=0x43;
- emsRegs.x.bx=(NUM_MESSAGES+MSGS_PER_PAGE)/MSGS_PER_PAGE;
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah);
- return;
- }
- printf("Allocated %d pages to handle %d\n",
- emsRegs.x.bx, emsRegs.x.dx);
- emsHandle = emsRegs.x.dx;
-
- /*----------------- Load EMS RAM with data -----------------*/
- msgBuf = p0; /* Set msgBuf array to physical page 0 */
- for (i=0; i<NUM_MESSAGES; i++)
- {
- sprintf(buff,"EMS message #%04d",i);
- if ( (i%100) == 0 ) fputc('.',stdout);
-
- page = i / MSGS_PER_PAGE;
- index = i % MSGS_PER_PAGE;
-
- /*--- Map indicated logical page into physical page 0 --*/
- emsRegs.h.ah = 0x44; /* Map EMS page cmd */
- emsRegs.x.bx = page; /* Logical page */
- emsRegs.h.al = 0; /* Physical page 0 */
- emsRegs.x.dx = emsHandle; /* EMS RAM handle */
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah); /* print error msg */
- i=NUM_MESSAGES; /* quit loop */
- continue; /* skip the strcpy */
- }
-
- /*- Copy the message into the appropriate EMS RAM slot -*/
- strcpy(msgBuf[index],buff);
- }
- fputc('\n',stdout);
-
- /*--- Allow the user to access any message in the buffer ---*/
- msgBuf = p3; /* Set msgBuf array to physical page 3 */
- do {
- printf("\nEnter message # to retrieve, or -1 to quit:");
- gets(buff);
- sscanf(buff,"%d",&i);
- if ( (i>=0) && (i<NUM_MESSAGES) )
- {
- page = i / MSGS_PER_PAGE;
- index = i % MSGS_PER_PAGE;
-
- /*----- Map indicated page into physical page 3 ----*/
- emsRegs.h.ah = 0x44; /* Map EMS page cmd */
- emsRegs.x.bx = page; /* Logical page */
- emsRegs.h.al = 3; /* Physical page 3 */
- emsRegs.x.dx = emsHandle; /* EMS RAM handle */
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah);/* print error msg */
- i = -1; /* quit loop */
- continue; /* skip the strcpy */
- }
-
- /*----------- Print the indicated message ----------*/
- printf("Page=%d, Index=%d, msg=%s\n",
- page, index, msgBuf+index);
- }
- } while (i != -1);
-
- /*----------- Free the EMS RAM back to EMS driver ----------*/
- emsRegs.h.ah=0x45;
- emsRegs.x.dx=emsHandle;
- int86(EMS_INT,&emsRegs,&emsRegs);
- if (emsRegs.h.ah)
- {
- emsPrintError(emsRegs.h.ah); /* Print error msg */
- return;
- }
- printf("Released all memory for handle %d\n",emsRegs.x.dx);
- }
-
- /****************************************************************
- * emsPrintError - print error message for value in AH *
- * *
- * INP: emsRegs - register set (AH holds status code) *
- ****************************************************************/
- void emsPrintError(int status)
- {
- char *s;
- switch (status)
- {
- case 0x00: s="Ok"; break;
- case 0x80: s="driver malfunction"; break;
- case 0x81: s="hardware malfunction"; break;
- case 0x83: s="bad handle"; break;
- case 0x84: s="undefined function"; break;
- case 0x85: s="no free handles"; break;
- case 0x86: s="page map context error"; break;
- case 0x87: s="insufficient memory pages"; break;
- case 0x88: s="Not enough free pages"; break;
- case 0x89: s="Can't allocate zero (0) pages"; break;
- case 0x8a: s="Logical page out of range"; break;
- case 0x8b: s="Physical page out of range"; break;
- case 0x8c: s="Page map hardware RAM full"; break;
- case 0x8d: s="Page map already has a handle"; break;
- case 0x8e: s="Page map not mapped to handle"; break;
- case 0x8f: s="Undefined subfunction number"; break;
- default: printf("EMS: unknown status=%02x",status);
- return;
- }
- printf("EMS: %s\n",s);
- }