Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/* This file contains the DOS memory allocator  */
23
 
24
#include <ll/i386/mem.h>
25
#include <ll/i386/x-bios.h>
26
#include <ll/i386/x-dosmem.h>
27
#include <ll/i386/error.h>
28
 
29
FILE(X - Dos - Memory);
30
 
31
/*
32
    We do not use the standard K&R pointer based memory allocator!
33
    This is because we cannot do pointer tricks easily with the GCC
34
    which only handles explicitely 32 bit non segmented address space.
35
    So we cannot use far pointers, and we cannot chain buckets of memory
36
    which are located in low memory area, beyond the accessibility
37
    of the ELF address space.
38
    A static allocation is so preferred; this should not give trouble
39
    since DOS memory is only used for reflection related purposes
40
*/
41
 
42
#define MAX_PARTITION   50      /* Max available partition */
43
 
44
static struct {
45
    BYTE used;
46
    LIN_ADDR addr;
47
    DWORD size;
48
} mem_table[MAX_PARTITION];
49
 
50
static int inited = 0;
51
 
52
void DOS_dump_mem(void)
53
{
54
    register int i;
55
    for (i = 0; i < MAX_PARTITION; i++) {
56
        if (mem_table[i].used)
57
            message("(%d) Addr : %p   Size : %lu/%lx\n",
58
                    i, mem_table[i].addr,
59
                    mem_table[i].size, mem_table[i].size);
60
    }
61
}
62
 
63
void DOS_mem_init(void)
64
{
65
    register int i;
66
 
67
    if (inited == 0) {
68
        mem_table[0].used = TRUE;
69
        X_meminfo(NULL, NULL, &(mem_table[0].addr), &(mem_table[0].size));
70
        for (i = 1; i < MAX_PARTITION; i++)
71
            mem_table[i].used = FALSE;
72
    } else {
73
        inited = 1;
74
    }
75
}
76
 
77
LIN_ADDR DOS_alloc(DWORD s)
78
{
79
    LIN_ADDR p = 0;
80
    int i = 0;
81
 
82
    while (i < MAX_PARTITION && p == NULL) {
83
        if (mem_table[i].used && (mem_table[i].size >= s))
84
            p = mem_table[i].addr;
85
        else
86
            i++;
87
    }
88
    if (p != 0) {
89
        if (mem_table[i].size > s) {
90
            mem_table[i].size -= s;
91
            mem_table[i].addr += s;
92
        } else
93
            mem_table[i].used = FALSE;
94
    }
95
    return (p);
96
}
97
 
98
int DOS_free(LIN_ADDR p, DWORD s)
99
{
100
    register int i = 1;
101
    unsigned i1 = 0, i2 = 0;
102
 
103
    while (i < MAX_PARTITION && ((i1 == 0) || (i2 == 0))) {
104
        if (mem_table[i].used) {
105
            if (mem_table[i].addr + mem_table[i].size == p)
106
                i1 = i;
107
            if (mem_table[i].addr == p + s)
108
                i2 = i;
109
        }
110
        i++;
111
    }
112
    if (i1 != 0 && i2 != 0) {
113
        mem_table[i1].size += mem_table[i2].size + s;
114
        mem_table[i2].used = FALSE;
115
    } else if (i1 == 0 && i2 != 0) {
116
        mem_table[i2].addr = p;
117
        mem_table[i2].size += s;
118
    } else if (i1 != 0 && i2 == 0)
119
        mem_table[i1].size += s;
120
    else {
121
        i = 0;
122
        while (i < MAX_PARTITION && (mem_table[i].used == TRUE))
123
            i++;
124
        if (i == MAX_PARTITION)
125
            return (FALSE);
126
        mem_table[i].addr = p;
127
        mem_table[i].size = s;
128
        mem_table[i].used = TRUE;
129
    }
130
    return (TRUE);
131
}