OSDN Git Service

wwww
[proj16/16.git] / src / lib / exmm / xmem.c
1 /*
2    Written by Alexander J. Russell 1994
3  
4    Placed in the public Domain by Alec Russell, March 1995
5  
6    Slightly higher level xms calls than xmem.asm
7  
8 */
9  
10 #include <stdio.h>
11 #include <io.h>
12 #include <string.h>
13 #include <malloc.h>
14  
15 #include "src\lib\exmm\xmem.h"
16  
17 xms_head_t xms_head={0};  // set handle to zero
18  
19  
20 /* ---------------------- alloc_xms() ----------------- February 19,1994 */
21 short alloc_xms(unsigned short far *size)  // size in 16k blocks
22 {
23    return(XMS_alloc(0, size));
24 }
25  
26  
27  
28 /* ---------------------- xms_to_mem() ---------------- February 19,1994 */
29 short xms_to_mem(unsigned short handle, void far *p, unsigned long off,
30 unsigned short n)
31 {
32    unsigned short block, boff;
33  
34    block=off >> XMSBLOCKSHIFT;
35    boff=off - (block << XMSBLOCKSHIFT);
36  
37    return(XMStoMem(handle, block, boff, n, p));
38 }
39  
40  
41 /* ---------------------- mem_to_xms() ---------------- February 19,1994 */
42 short mem_to_xms(unsigned short handle, void far *p, unsigned long off,
43 unsigned short n)
44 {
45    unsigned short block, boff;
46  
47    block=off >> XMSBLOCKSHIFT;
48    boff=off - (block << XMSBLOCKSHIFT);
49  
50    return(MemToXMS(handle, block, boff, n, p));
51 }
52  
53  
54 /* ---------------------- qalloc_xms() -------------------- March 8,1994 */
55 xms_node_t *qalloc_xms(unsigned long size)
56 {
57    xms_node_t *node=NULL;
58    xms_node_t *t1;
59  
60    if ( size <= xms_head.avail )
61       {
62       // look for existing node
63       t1=xms_head.next;
64       while ( t1 )
65          {
66          if ( t1->used == 0 && t1->size >= size )
67             {
68             t1->off=0;
69             t1->used=1;
70             node=t1;
71             break;
72             }
73          else
74             t1=t1->next;
75          }
76  
77       if ( node == NULL ) // didn't find existing node
78          {
79          node=malloc(sizeof(xms_node_t));
80          if ( node )
81             {
82             node->off=0;
83             node->used=1;
84             node->size=size;
85             node->next=NULL;
86             node->start=xms_head.next_off;
87             xms_head.avail-=size;
88             xms_head.next_off+=size;
89             if ( xms_head.next == NULL )
90                {
91                xms_head.next=node;
92                }
93             else
94                {
95                t1=xms_head.next;
96                while ( t1->next )
97                   t1=t1->next;
98                t1->next=node;
99                }
100             }
101          else
102             printf("out of near mem in qalloc_xms");
103          }
104       }
105    else
106       printf("out of xms mem in qalloc size %lu avail %lu", size,
107 xms_head.avail);
108  
109    return(node);
110 }
111  
112  
113 /* ---------------------- qfree_xms() --------------------- March 8,1994 */
114 void qfree_xms(xms_node_t *node)
115 {
116    xms_node_t *t1;
117  
118    if ( xms_head.next )
119       {
120       t1=xms_head.next;
121       while ( t1 != node && t1 )
122          t1=t1->next;
123  
124       if ( t1 )
125          {
126          t1->used=0;
127          }
128       else
129          printf("ERROR didn't find node qfree");
130       }
131    else
132       {
133       printf("ATTEMPTED to qfree empty list");
134       }
135 }
136  
137  
138  
139 /* ---------------------- xms_open() ---------------------- March 8,1994 */
140 xms_node_t *xms_open(char *file)
141 {
142    int i;
143    xms_node_t *node=NULL;
144    FILE *fp;
145    char *buffer;
146    unsigned long off;
147  
148    fp=fopen(file, "rb");
149    if ( fp )
150       {
151       node=qalloc_xms(filelength(fileno(fp)));
152       if ( node )
153          {
154          buffer=malloc(4096);
155          if ( buffer )
156             {
157             off=0l;
158             while ( (i=fread(buffer, 1, 4096, fp)) )
159                {
160                mem_to_xms(xms_head.handle, (char far *)buffer,
161 off+node->start, i);
162                off+=i;
163                }
164  
165             free(buffer);
166             }
167          else
168             printf("out of mem in xms_open 1");
169          }
170  
171       fclose(fp);
172       }
173    else
174       printf("ERROR opening %s in xms_open", file);
175  
176    return(node);
177 }
178  
179  
180 /* ---------------------- xms_read() ---------------------- March 8,1994 */
181 short xms_read(void far *buffer, unsigned short n, xms_node_t *node)
182 {
183  
184    if ( node->off >= node->size )
185       return 0;
186  
187    if ( n+node->off > node->size )
188       n=node->size - node->off;
189  
190    xms_to_mem(xms_head.handle, buffer, node->start+node->off, n);
191    node->off+=n;
192  
193    return(n);
194 }
195  
196  
197 /* ---------------------- xms_write() ---------------------- March 8,1994 */
198 short xms_write(void far *buffer, unsigned short n, xms_node_t *node)
199 {
200  
201    if ( node->off >= node->size )
202       return 0;
203  
204    if ( n+node->off > node->size )
205       n=node->size - node->off;
206  
207    mem_to_xms(xms_head.handle, buffer, node->start+node->off, n);
208    node->off+=n;
209  
210    return(n);
211 }
212  
213  
214 /* ---------------------- xms_tell() ---------------------- March 8,1994 */
215 long xms_tell(xms_node_t *node)
216 {
217    return node->off;
218 }
219  
220  
221  
222 /* ---------------------- xms_seek() ---------------------- March 8,1994 */
223 short xms_seek(xms_node_t *node, long off, short whence)
224 {
225    short err=0;
226  
227    switch ( whence )
228       {
229       case SEEK_SET:
230          if ( off < 0l || off > node->size )
231             err=1;
232          else
233             node->off=off;
234          break;
235  
236       case SEEK_END:
237          if ( off > 0l || (node->size + off) < 0l )
238             err=1;
239          else
240             node->off=node->size + off;
241          break;
242  
243       case SEEK_CUR:
244          if ( node->off + off < 0l || node->off + off > node->size )
245             err=1;
246          else
247             node->off+=off;
248          break;
249       }
250  
251    return(err);
252 }
253  
254  
255 /* ---------------------- xms_close() --------------------- March 8,1994 */
256 void xms_close(xms_node_t *node)
257 {
258    qfree_xms(node);
259 }
260  
261  
262  
263  
264 /* ---------------------- init_xms() ---------------------- March 8,1994 */
265 short init_xms(unsigned short min_blocks)
266 {
267    unsigned short blocks;
268  
269    blocks=XMSblk_available();
270    if ( blocks >= min_blocks )
271       {
272       memset(&xms_head, 0, sizeof(xms_head_t));
273       if ( (xms_head.handle=alloc_xms(&blocks)) )
274          {
275          printf("blocks minus by = %u", blocks);
276          min_blocks-=blocks;
277          xms_head.avail=xms_head.total=(unsigned long)min_blocks*XMSBLOCK;
278          blocks=min_blocks;
279          }
280       else
281          blocks=0;
282       }
283    else
284       blocks=0;
285  
286    return(blocks);
287 }
288  
289  
290 /* ---------------------- deinit_xms() -------------------- March 8,1994 */
291 void deinit_xms(void)
292 {
293    xms_node_t *t1, *t2;
294  
295    if ( xms_head.handle )
296       {
297       XMS_dealloc(xms_head.handle);
298       if ( xms_head.next )
299          {
300          t1=xms_head.next;
301          t2=t1->next;
302          while ( t1 )
303             {
304             free(t1);
305             t1=t2;
306             t2=t1->next;
307             }
308          }
309  
310       memset(&xms_head, 0, sizeof(xms_head_t));
311       }
312 }
313  
314  
315  
316 /* --------------------------- end of file ------------------------- */
317
318 /*\r
319 \r
320 Not sure how to use this?\r
321 \r
322 call init_xms(x) to allocate a big chunk of xms.\r
323 x is in 'blocks' of 16Kb. Pick X big enough to buffer all the files\r
324 you want to place in xms.\r
325 \r
326 call xms_open("filename); for each file to be buffered. This copies the file\r
327 int xms.\r
328 \r
329 then use xms_read(), xms_write(), and xms_seek() to read the file from\r
330 xms instead of disk.\r
331 \r
332 call deinit_xms() just before exit to clean up.\r
333 \r
334 You can also use the lower level calls directly.\r
335 \r
336 */