]> 4ch.mooo.com Git - 16.git/blob - src/lib/ems.c
modified: scroll.exe
[16.git] / src / lib / ems.c
1 //------- PRACE S EMS pameti ---------------\r
2 #include <stdio.h>\r
3 #include <fcntl.h>\r
4 #include <io.h>\r
5 #include <dos.h>\r
6 #include <mem.h>\r
7 \r
8 typedef struct\r
9   {\r
10   unsigned long length;         /* velikost prenasene pameti      */\r
11   unsigned int sourceH;         /* handle pro zdroj (0=konvencni  */\r
12   unsigned long sourceOff;      /* offset zdroje pameti           */\r
13   unsigned int destH;           /* handle pro terc (0=konvencni   */\r
14   unsigned long destOff;        /* offset terce pameti            */\r
15   } XMOVE;\r
16 \r
17 int get_emem(void);             // Fce pro zachazeni s EMS\r
18 int alloc_emem(int n);          // Alokuje n KB pameti, vraci handle\r
19 int dealloc_emem(int h);        // Dealokuje EMS (handle)\r
20 int move_emem(XMOVE *p);        // presune blok z/do EMS\r
21 int mem_emem(unsigned *total, unsigned *free);\r
22 \r
23 #define  pagesizeEMS 0x4000       // pamet EMS je ze 16k stranek\r
24 \r
25 //int   pagesAllocated = 0;\r
26 //int   totalPages;\r
27 char *EmsFrame;\r
28 \r
29 \r
30 //------ Zda je EMS driver dostupny: ret=  1 - ANO, 0 - NE\r
31 int isEMS(void)\r
32 {\r
33     int fh;\r
34     union REGS rg;\r
35 \r
36     if((fh=open("EMMXXXX0",O_RDONLY,&fh)) == -1) return( 0 );\r
37 \r
38     rg.h.ah = 0x44;\r
39     rg.h.al = 0x00;\r
40     rg.x.bx = fh;\r
41     int86(0x21,&rg,&rg);\r
42     close(fh);\r
43     if(rg.x.cflag) return(0);\r
44     if(rg.x.dx & 0x80)\r
45      return( 1 );\r
46     else\r
47      return( 0 );\r
48 }\r
49 \r
50 //----- Zda je EMS HW dostupny ret=  1 - ANO, 0 - NE\r
51 int checkEMS(void)\r
52 {\r
53     union REGS rg;\r
54 \r
55     rg.h.ah = 0x40;\r
56     int86(0x67,&rg,&rg);\r
57     if(rg.h.ah == 0)\r
58      return( 1 );\r
59     else\r
60      return( 0 );\r
61 }\r
62 \r
63 //----- Vraci totalni pocet stranek EMS nebo -1 ----\r
64 int coretotalEMS(void)\r
65 {\r
66     union REGS rg;\r
67 \r
68     rg.h.ah = 0x42;\r
69     int86(0x67,&rg,&rg);\r
70     if(rg.x.cflag) return( -1 );\r
71     //if(!pagesAllocated)\r
72     // { pagesAllocated = 1;\r
73     //   totalPages = rg.x.dx;\r
74     // }\r
75     return(rg.x.bx);\r
76 }\r
77 \r
78 //----- Vraci pocet volnych stranek EMS nebo -1 ----\r
79 int coreleftEMS(void)\r
80 {\r
81     union REGS rg;\r
82 \r
83     //if(pagesAllocated) return(totalPages);\r
84     rg.h.ah = 0x42;\r
85     int86(0x67,&rg,&rg);\r
86     if(rg.x.cflag) return( -1 );\r
87     //if(!pagesAllocated)\r
88     //pagesAllocated = 1;\r
89     //totalPages = rg.x.dx;\r
90     //return(totalPages);\r
91     return(rg.x.dx);\r
92 }\r
93 \r
94 //----- Vraci EMS page frame (pointr na EMS) nebo NULL ----\r
95 char *pageframeEMS(void)\r
96 {\r
97     union REGS rg;\r
98 \r
99     rg.h.ah = 0x41;\r
100     int86(0x67,&rg,&rg);\r
101     if(rg.h.ah != 0)\r
102      return( NULL );\r
103     else\r
104      return((char *)MK_FP(rg.x.bx,0));\r
105 }\r
106 \r
107 //----- Alokuje n stranek - vraci handle na blok stranek nebo 0 ----\r
108 unsigned mallocEMS(int n)\r
109 {\r
110     union REGS rg;\r
111 \r
112     if(n > coreleftEMS() ) return( 0 );\r
113     rg.h.ah = 0x43;\r
114     rg.x.bx = n;\r
115     int86(0x67,&rg,&rg);\r
116     if(rg.h.ah)\r
117      return( 0 );\r
118     else\r
119      return(rg.x.dx);\r
120 }\r
121 \r
122 //----- Dealokuje blok stranek ret = 1-O.K. 0-ERR -----\r
123 unsigned freeEMS(unsigned h)\r
124 {\r
125     union REGS rg;\r
126     int   i;\r
127 \r
128     for(i=0; i<5; i++)\r
129      { rg.h.ah = 0x45;\r
130        rg.x.dx = h;\r
131        int86(0x67,&rg,&rg);\r
132        if(rg.h.ah == 0) break;\r
133      }\r
134     if(rg.h.ah == 0)\r
135      return( 1 );\r
136     else\r
137      return( 0 );\r
138 }\r
139 \r
140 //----- Mapuje logiclou stranku do fyzicke stranky\r
141 int mapEMS(unsigned h, int Ppage, int Lpage)\r
142 {\r
143     union REGS rg;\r
144 \r
145     if(Ppage < 0 || Ppage > 3) return( 0 );\r
146     rg.h.ah = 0x44;\r
147     rg.h.al = Ppage;\r
148     rg.x.bx = Lpage;\r
149     rg.x.dx = h;\r
150     int86(0x67,&rg,&rg);\r
151     if(rg.h.ah != 0)\r
152      return( 0 );\r
153     else\r
154      return( 1 );\r
155 }\r
156 \r
157 // ##### Fce se stejnymi parametry pro EMS jako pro XMS\r
158 \r
159 //----- Zda je EMS dostupna\r
160 int get_emem(void)\r
161 {\r
162   int ist;\r
163 \r
164   ist = checkEMS();\r
165   if(ist == 1)\r
166   { ist = isEMS();\r
167     if(ist == 1) return( 0x0300 );\r
168   }\r
169   return( -1 );\r
170 }\r
171 \r
172 //----- Allokuje Kb pameti -------\r
173 int alloc_emem(int kb)\r
174 {\r
175    int Pages,hhh;\r
176 \r
177    Pages = kb / 16;\r
178    if((Pages * 16) < kb) Pages++;\r
179 \r
180    hhh = mallocEMS(Pages);\r
181    if(hhh == 0)\r
182     return( -1);\r
183    else\r
184     return(hhh);\r
185 }\r
186 \r
187 //----- dealokuje EMS pres handle\r
188 int dealloc_emem(int h)\r
189 {\r
190    return( freeEMS( h ) );\r
191 }\r
192 \r
193 //----- presune blok pameti\r
194 //  unsigned long length;         /* velikost prenasene pameti      */\r
195 //  unsigned int  sourceH;        /* handle pro zdroj (0=konvencni  */\r
196 //  unsigned long sourceOff;      /* offset zdroje pameti           */\r
197 //  unsigned int  destH;          /* handle pro terc (0=konvencni   */\r
198 //  unsigned long destOff;        /* offset terce pameti            */\r
199 int move_emem(XMOVE *pxm)\r
200 {\r
201    unsigned char *SrcBuf,*DstBuf;\r
202    int      ist;\r
203    unsigned int  SrcOff, DstOff, BegPage, BegOff, FreeByte, CopyLen;\r
204 \r
205    if(pxm->sourceH == 0 && pxm->destH != 0)    // Buffer->EMS\r
206    {\r
207      SrcBuf  = (unsigned char *)pxm->sourceOff;// buffer\r
208      SrcOff  = 0;\r
209      BegPage = pxm->destOff / pagesizeEMS;     // pocatecni page\r
210      BegOff  = pxm->destOff % pagesizeEMS;     // offset in page\r
211      FreeByte= pagesizeEMS - BegOff;           // volnych B na page\r
212      CopyLen = pxm->length;                    // celkova delka\r
213 \r
214      Next_page:\r
215      if(CopyLen > FreeByte)\r
216      {\r
217        ist = mapEMS(pxm->destH, 0, BegPage);\r
218        if(ist==0) return( 0 );\r
219        memcpy(EmsFrame+BegOff, SrcBuf+SrcOff, FreeByte);\r
220 \r
221        CopyLen  = CopyLen - FreeByte;\r
222        SrcOff  += FreeByte;\r
223        BegPage++;\r
224        BegOff   = 0;\r
225        FreeByte = pagesizeEMS;\r
226        goto Next_page;\r
227      }\r
228      else\r
229      {\r
230        ist = mapEMS(pxm->destH, 0, BegPage);\r
231        if(ist==0) return( 0 );\r
232        memcpy(EmsFrame+BegOff, SrcBuf+SrcOff, CopyLen);\r
233      }\r
234    }\r
235    else if(pxm->sourceH != 0 && pxm->destH == 0) // EMS->Buffer\r
236    {\r
237      DstBuf  = (unsigned char *)pxm->destOff;// buffer\r
238      DstOff  = 0;\r
239      BegPage = pxm->sourceOff / pagesizeEMS;     // pocatecni page\r
240      BegOff  = pxm->sourceOff % pagesizeEMS;     // offset in page\r
241      FreeByte= pagesizeEMS - BegOff;             // volnych B na page\r
242      CopyLen = pxm->length;                    // celkova delka\r
243 \r
244      Next_page2:\r
245      if(CopyLen > FreeByte)\r
246      {\r
247        ist = mapEMS(pxm->sourceH, 0, BegPage);\r
248        if(ist==0) return( 0 );\r
249        memcpy(DstBuf+DstOff, EmsFrame+BegOff, FreeByte);\r
250 \r
251        CopyLen  = CopyLen - FreeByte;\r
252        DstOff  += FreeByte;\r
253        BegPage++;\r
254        BegOff   = 0;\r
255        FreeByte = pagesizeEMS;\r
256        goto Next_page2;\r
257      }\r
258      else\r
259      {\r
260        ist = mapEMS(pxm->sourceH, 0, BegPage);\r
261        if(ist==0) return( 0 );\r
262        memcpy(DstBuf+DstOff, EmsFrame+BegOff, CopyLen);\r
263      }\r
264    }\r
265    else   // Error\r
266    { return( 0 );\r
267    }\r
268 \r
269    return 1;\r
270 }\r
271 \r
272 // ----- Vrati pocet volnych a max. KB EMS\r
273 int mem_emem(unsigned int *total, unsigned int *freeall)\r
274 {\r
275  int pom;\r
276 \r
277  pom = coretotalEMS();\r
278  if(pom != -1 )\r
279   *total = pom * 16;\r
280  else\r
281   return( 0 );\r
282  pom = coreleftEMS();\r
283  if(pom != -1)\r
284   *freeall = pom * 16;\r
285  else\r
286   return( 0 );\r
287 \r
288  return( 1 );\r
289 }\r