-//------- PRACE S EMS pameti ---------------\r
-#include <stdio.h>\r
-#include <fcntl.h>\r
-#include <io.h>\r
-#include <dos.h>\r
-#include <mem.h>\r
-\r
-typedef struct\r
- {\r
- unsigned long length; /* velikost prenasene pameti */\r
- unsigned int sourceH; /* handle pro zdroj (0=konvencni */\r
- unsigned long sourceOff; /* offset zdroje pameti */\r
- unsigned int destH; /* handle pro terc (0=konvencni */\r
- unsigned long destOff; /* offset terce pameti */\r
- } XMOVE;\r
-\r
-int get_emem(void); // Fce pro zachazeni s EMS\r
-int alloc_emem(int n); // Alokuje n KB pameti, vraci handle\r
-int dealloc_emem(int h); // Dealokuje EMS (handle)\r
-int move_emem(XMOVE *p); // presune blok z/do EMS\r
-int mem_emem(unsigned *total, unsigned *free);\r
-\r
-#define pagesizeEMS 0x4000 // pamet EMS je ze 16k stranek\r
-\r
-//int pagesAllocated = 0;\r
-//int totalPages;\r
-char *EmsFrame;\r
-\r
-\r
-//------ Zda je EMS driver dostupny: ret= 1 - ANO, 0 - NE\r
-int isEMS(void)\r
-{\r
- int fh;\r
- union REGS rg;\r
-\r
- if((fh=open("EMMXXXX0",O_RDONLY,&fh)) == -1) return( 0 );\r
-\r
- rg.h.ah = 0x44;\r
- rg.h.al = 0x00;\r
- rg.x.bx = fh;\r
- int86(0x21,&rg,&rg);\r
- close(fh);\r
- if(rg.x.cflag) return(0);\r
- if(rg.x.dx & 0x80)\r
- return( 1 );\r
- else\r
- return( 0 );\r
-}\r
-\r
-//----- Zda je EMS HW dostupny ret= 1 - ANO, 0 - NE\r
-int checkEMS(void)\r
-{\r
- union REGS rg;\r
-\r
- rg.h.ah = 0x40;\r
- int86(0x67,&rg,&rg);\r
- if(rg.h.ah == 0)\r
- return( 1 );\r
- else\r
- return( 0 );\r
-}\r
-\r
-//----- Vraci totalni pocet stranek EMS nebo -1 ----\r
-int coretotalEMS(void)\r
-{\r
- union REGS rg;\r
-\r
- rg.h.ah = 0x42;\r
- int86(0x67,&rg,&rg);\r
- if(rg.x.cflag) return( -1 );\r
- //if(!pagesAllocated)\r
- // { pagesAllocated = 1;\r
- // totalPages = rg.x.dx;\r
- // }\r
- return(rg.x.bx);\r
-}\r
-\r
-//----- Vraci pocet volnych stranek EMS nebo -1 ----\r
-int coreleftEMS(void)\r
-{\r
- union REGS rg;\r
-\r
- //if(pagesAllocated) return(totalPages);\r
- rg.h.ah = 0x42;\r
- int86(0x67,&rg,&rg);\r
- if(rg.x.cflag) return( -1 );\r
- //if(!pagesAllocated)\r
- //pagesAllocated = 1;\r
- //totalPages = rg.x.dx;\r
- //return(totalPages);\r
- return(rg.x.dx);\r
-}\r
-\r
-//----- Vraci EMS page frame (pointr na EMS) nebo NULL ----\r
-char *pageframeEMS(void)\r
-{\r
- union REGS rg;\r
-\r
- rg.h.ah = 0x41;\r
- int86(0x67,&rg,&rg);\r
- if(rg.h.ah != 0)\r
- return( NULL );\r
- else\r
- return((char *)MK_FP(rg.x.bx,0));\r
-}\r
-\r
-//----- Alokuje n stranek - vraci handle na blok stranek nebo 0 ----\r
-unsigned mallocEMS(int n)\r
-{\r
- union REGS rg;\r
-\r
- if(n > coreleftEMS() ) return( 0 );\r
- rg.h.ah = 0x43;\r
- rg.x.bx = n;\r
- int86(0x67,&rg,&rg);\r
- if(rg.h.ah)\r
- return( 0 );\r
- else\r
- return(rg.x.dx);\r
-}\r
-\r
-//----- Dealokuje blok stranek ret = 1-O.K. 0-ERR -----\r
-unsigned freeEMS(unsigned h)\r
-{\r
- union REGS rg;\r
- int i;\r
-\r
- for(i=0; i<5; i++)\r
- { rg.h.ah = 0x45;\r
- rg.x.dx = h;\r
- int86(0x67,&rg,&rg);\r
- if(rg.h.ah == 0) break;\r
+/*
+
+ THE IBM PC PROGRAMMER'S GUIDE TO C\r
+ \r
+ \r
+ \r
+ 3rd Edition\r
+ \r
+ \r
+ \r
+ Matthew Probert\r
+\r
+\r
+ \r
+ COPYRIGHT NOTICE\r
+\r
+\r
+This publication remains the property of Matthew Probert. License is\r
+hereby given for this work to be freely distibuted in whole under the\r
+proviso that credit is given to the author. Sections of this work may be\r
+used and distributed without payment under the proviso that credit is\r
+given to both this work and the author. Source code occuring in this work\r
+may be used within commercial and non-commercial applications without\r
+charge and without reference to the author.
+*/
+ /*\r
+ Various functions for using Expanded memory\r
+ */\r
+#include "src\lib\ems.h"\r
+ emmtest()\r
+ {\r
+ /*\r
+ Tests for the presence of expnaded memory by attempting to\r
+ open the file EMMXXXX0.\r
+ */\r
+ \r
+ union REGS regs;\r
+ struct SREGS sregs;\r
+ int error;\r
+ long handle;\r
+ \r
+ /* Attempt to open the file device EMMXXXX0 */\r
+ regs.x.ax = 0x3d00;\r
+ regs.x.dx = (int)"EMMXXXX0";\r
+ sregs.ds = 0; //????\r
+ intdosx(®s,®s,&sregs);\r
+ handle = regs.x.ax;\r
+ error = regs.x.cflag;\r
+ \r
+ if (!error)\r
+ {\r
+ regs.h.ah = 0x3e;\r
+ regs.x.bx = handle;\r
+ intdos(®s,®s);\r
+ }\r
+ return error;\r
}\r
- if(rg.h.ah == 0)\r
- return( 1 );\r
- else\r
- return( 0 );\r
-}\r
-\r
-//----- Mapuje logiclou stranku do fyzicke stranky\r
-int mapEMS(unsigned h, int Ppage, int Lpage)\r
-{\r
- union REGS rg;\r
-\r
- if(Ppage < 0 || Ppage > 3) return( 0 );\r
- rg.h.ah = 0x44;\r
- rg.h.al = Ppage;\r
- rg.x.bx = Lpage;\r
- rg.x.dx = h;\r
- int86(0x67,&rg,&rg);\r
- if(rg.h.ah != 0)\r
- return( 0 );\r
- else\r
- return( 1 );\r
-}\r
-\r
-// ##### Fce se stejnymi parametry pro EMS jako pro XMS\r
-\r
-//----- Zda je EMS dostupna\r
-int get_emem(void)\r
-{\r
- int ist;\r
-\r
- ist = checkEMS();\r
- if(ist == 1)\r
- { ist = isEMS();\r
- if(ist == 1) return( 0x0300 );\r
- }\r
- return( -1 );\r
-}\r
-\r
-//----- Allokuje Kb pameti -------\r
-int alloc_emem(int kb)\r
-{\r
- int Pages,hhh;\r
-\r
- Pages = kb / 16;\r
- if((Pages * 16) < kb) Pages++;\r
-\r
- hhh = mallocEMS(Pages);\r
- if(hhh == 0)\r
- return( -1);\r
- else\r
- return(hhh);\r
-}\r
-\r
-//----- dealokuje EMS pres handle\r
-int dealloc_emem(int h)\r
-{\r
- return( freeEMS( h ) );\r
-}\r
-\r
-//----- presune blok pameti\r
-// unsigned long length; /* velikost prenasene pameti */\r
-// unsigned int sourceH; /* handle pro zdroj (0=konvencni */\r
-// unsigned long sourceOff; /* offset zdroje pameti */\r
-// unsigned int destH; /* handle pro terc (0=konvencni */\r
-// unsigned long destOff; /* offset terce pameti */\r
-int move_emem(XMOVE *pxm)\r
-{\r
- unsigned char *SrcBuf,*DstBuf;\r
- int ist;\r
- unsigned int SrcOff, DstOff, BegPage, BegOff, FreeByte, CopyLen;\r
-\r
- if(pxm->sourceH == 0 && pxm->destH != 0) // Buffer->EMS\r
- {\r
- SrcBuf = (unsigned char *)pxm->sourceOff;// buffer\r
- SrcOff = 0;\r
- BegPage = pxm->destOff / pagesizeEMS; // pocatecni page\r
- BegOff = pxm->destOff % pagesizeEMS; // offset in page\r
- FreeByte= pagesizeEMS - BegOff; // volnych B na page\r
- CopyLen = pxm->length; // celkova delka\r
-\r
- Next_page:\r
- if(CopyLen > FreeByte)\r
+ \r
+ emmok()\r
{\r
- ist = mapEMS(pxm->destH, 0, BegPage);\r
- if(ist==0) return( 0 );\r
- memcpy(EmsFrame+BegOff, SrcBuf+SrcOff, FreeByte);\r
-\r
- CopyLen = CopyLen - FreeByte;\r
- SrcOff += FreeByte;\r
- BegPage++;\r
- BegOff = 0;\r
- FreeByte = pagesizeEMS;\r
- goto Next_page;\r
+ /*\r
+ Checks whether the expanded memory manager responds correctly\r
+ */\r
+ \r
+ union REGS regs;\r
+ \r
+ regs.h.ah = 0x40;\r
+ int86(EMM,®s,®s);\r
+ \r
+ if (regs.h.ah)\r
+ return 0;\r
+ \r
+ regs.h.ah = 0x41;\r
+ int86(EMM,®s,®s);\r
+ \r
+ if (regs.h.ah)\r
+ return 0;\r
+ \r
+ emmbase = MK_FP(regs.x.bx,0);\r
+ return 1;\r
}\r
- else\r
+ \r
+ long emmavail()\r
{\r
- ist = mapEMS(pxm->destH, 0, BegPage);\r
- if(ist==0) return( 0 );\r
- memcpy(EmsFrame+BegOff, SrcBuf+SrcOff, CopyLen);\r
+ /*\r
+ Returns the number of available (free) 16K pages of expanded\r
+ memory\r
+ or -1 if an error occurs.\r
+ */\r
+ \r
+ union REGS regs;\r
+ \r
+ regs.h.ah = 0x42;\r
+ int86(EMM,®s,®s);\r
+ if (!regs.h.ah)\r
+ return regs.x.bx;\r
+ return -1;\r
}\r
- }\r
- else if(pxm->sourceH != 0 && pxm->destH == 0) // EMS->Buffer\r
- {\r
- DstBuf = (unsigned char *)pxm->destOff;// buffer\r
- DstOff = 0;\r
- BegPage = pxm->sourceOff / pagesizeEMS; // pocatecni page\r
- BegOff = pxm->sourceOff % pagesizeEMS; // offset in page\r
- FreeByte= pagesizeEMS - BegOff; // volnych B na page\r
- CopyLen = pxm->length; // celkova delka\r
-\r
- Next_page2:\r
- if(CopyLen > FreeByte)\r
+ \r
+ long emmalloc(int n)\r
{\r
- ist = mapEMS(pxm->sourceH, 0, BegPage);\r
- if(ist==0) return( 0 );\r
- memcpy(DstBuf+DstOff, EmsFrame+BegOff, FreeByte);\r
-\r
- CopyLen = CopyLen - FreeByte;\r
- DstOff += FreeByte;\r
- BegPage++;\r
- BegOff = 0;\r
- FreeByte = pagesizeEMS;\r
- goto Next_page2;\r
+ /*\r
+ Requests 'n' pages of expanded memory and returns the file\r
+ handle\r
+ assigned to the pages or -1 if there is an error\r
+ */\r
+ \r
+ union REGS regs;\r
+ \r
+ regs.h.ah = 0x43;\r
+ regs.x.bx = n;\r
+ int86(EMM,®s,®s);\r
+ if (regs.h.ah)\r
+ return -1;\r
+ return regs.x.dx;\r
}\r
- else\r
+ \r
+ emmmap(long handle, int phys, int page)\r
{\r
- ist = mapEMS(pxm->sourceH, 0, BegPage);\r
- if(ist==0) return( 0 );\r
- memcpy(DstBuf+DstOff, EmsFrame+BegOff, CopyLen);\r
+ /*\r
+ Maps a physical page from expanded memory into the page frame\r
+ in the\r
+ conventional memory 16K window so that data can be transfered\r
+ between\r
+ the expanded memory and conventional memory.\r
+ */\r
+ \r
+ union REGS regs;\r
+ \r
+ regs.h.ah = 0x44;\r
+ regs.h.al = page;\r
+ regs.x.bx = phys;\r
+ regs.x.dx = handle;\r
+ int86(EMM,®s,®s);\r
+ return (regs.h.ah == 0);\r
}\r
- }\r
- else // Error\r
- { return( 0 );\r
- }\r
-\r
- return 1;\r
-}\r
-\r
-// ----- Vrati pocet volnych a max. KB EMS\r
-int mem_emem(unsigned int *total, unsigned int *freeall)\r
-{\r
- int pom;\r
-\r
- pom = coretotalEMS();\r
- if(pom != -1 )\r
- *total = pom * 16;\r
- else\r
- return( 0 );\r
- pom = coreleftEMS();\r
- if(pom != -1)\r
- *freeall = pom * 16;\r
- else\r
- return( 0 );\r
-\r
- return( 1 );\r
-}\r
+ \r
+ void emmmove(int page, char *str, int n)\r
+ {\r
+ /*\r
+ Move 'n' bytes from conventional memory to the specified\r
+ expanded memory\r
+ page\r
+ */\r
+ \r
+ char far *ptr;\r
+ \r
+ ptr = emmbase + page * 16384;\r
+ while(n-- > 0)\r
+ *ptr++ = *str++;\r
+ }\r
+ \r
+ void emmget(int page, char *str, int n)\r
+ {\r
+ /*\r
+ Move 'n' bytes from the specified expanded memory page into\r
+ conventional\r
+ memory\r
+ */\r
+ \r
+ char far *ptr;\r
+ \r
+ ptr = emmbase + page * 16384;\r
+ while(n-- > 0)\r
+ *str++ = *ptr++;\r
+ }\r
+ \r
+ emmclose(long handle)\r
+ {\r
+ /*\r
+ Release control of the expanded memory pages allocated to\r
+ 'handle'\r
+ */\r
+ \r
+ union REGS regs;\r
+ \r
+ regs.h.ah = 0x45;\r
+ regs.x.dx = handle;\r
+ int86(EMM,®s,®s);\r
+ return (regs.h.ah == 0);\r
+ }
+++ /dev/null
-#if !defined(__EMS_H)\r
-#define __EMS_H\r
-\r
-#define EMSPAGESIZE (4096)\r
-#define EMS_ERROR (-1)\r
-struct {\r
- unsigned long length;\r
- unsigned char source_type;\r
- unsigned int source_handle;\r
- unsigned int source_ofs; \r
- unsigned int source_seg;\r
- unsigned char dest_type;\r
- unsigned int dest_handle;\r
- unsigned int dest_ofs; \r
- unsigned int dest_seg;\r
-} myEMSmove;\r
-\r
-\r
-void conv2ems(int PAGE, int HANDLE, char *output) {\r
- char *x = (char *) &myEMSmove;\r
- myEMSmove.length = EMSPAGESIZE;\r
- myEMSmove.source_type = 0;\r
- myEMSmove.source_handle = 0;\r
- myEMSmove.source_ofs = FP_OFF(output);\r
- myEMSmove.source_seg = FP_SEG(output);\r
- myEMSmove.dest_type = 1;\r
- myEMSmove.dest_handle = HANDLE;\r
- myEMSmove.dest_ofs = (PAGE & 3) << 12;\r
- myEMSmove.dest_seg = PAGE >> 2;\r
- __asm push ds\r
- __asm mov ax, 5700h; \r
- __asm lds si, x\r
- __asm int 67h \r
- __asm pop ds\r
-}\r
-\r
-void ems2conv(int PAGE, int HANDLE, char *output) {\r
- char *x = (char *) &myEMSmove;\r
- myEMSmove.length = EMSPAGESIZE;\r
- myEMSmove.source_type = 1;\r
- myEMSmove.source_handle = HANDLE;\r
- myEMSmove.source_ofs = (PAGE & 3) << 12;\r
- myEMSmove.source_seg = PAGE>>2;\r
- myEMSmove.dest_type = 0;\r
- myEMSmove.dest_handle = 0;\r
- myEMSmove.dest_ofs = FP_OFF(output);\r
- myEMSmove.dest_seg = FP_SEG(output);\r
- __asm push ds\r
- __asm mov ax, 5700h\r
- __asm lds si, x\r
- __asm int 67h \r
- __asm pop ds\r
-}\r
-\r
-\r
-void freeEMS(int handle) {\r
- __asm mov dx, handle;\r
- __asm mov ah, 45h; \r
- __asm int 67h \r
-}\r
-\r
-int checkEMS() {\r
- char *x = "EMMXXXX0";\r
- __asm {\r
- mov ax, 3567h\r
- int 21h\r
- mov di, 10\r
- mov si, offset x\r
- mov cx, 4\r
- rep cmpsw\r
- je good \r
- }\r
- return -1;\r
- good:\r
- __asm {\r
- sub ax, ax\r
- mov ah, 40h\r
- int 67h\r
- }\r
- return _AX;\r
-}\r
-\r
-int getavailEMS() {\r
- __asm {\r
- mov ah, 42h\r
- int 67h\r
- cmp ah, 00h\r
- je getavailEMS_Okay\r
- mov bx, -1\r
- }\r
- getavailEMS_Okay:\r
- __asm shl bx, 2\r
- return _BX;\r
-}\r
-\r
-int allocEMS(int pages) {\r
- __asm {\r
- mov bx, pages\r
- shr bx, 2\r
- mov ah, 43h\r
- int 67h\r
- cmp ah, 0\r
- je allocEMS_Okay\r
- mov dx, -1\r
- }\r
- allocEMS_Okay:\r
- return _DX;\r
-}\r
-\r
-#endif\r