7 #define REAL_MEM_BLOCKS 0x100
12 unsigned int size
: 20;
13 unsigned int free
: 1;
19 struct mem_block blocks
[REAL_MEM_BLOCKS
];
22 static int map_file(void *start
, size_t length
, int prot
, int flags
, char *name
, long offset
)
27 fd
= open(name
, (flags
& MAP_SHARED
) ? O_RDWR
: O_RDONLY
);
34 m
= mmap(start
, length
, prot
, flags
, fd
, offset
);
36 if (m
== (void *)-1) {
46 static int real_mem_init(void)
51 if (!map_file((void *)REAL_MEM_BASE
, REAL_MEM_SIZE
,
52 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
53 MAP_FIXED
| MAP_PRIVATE
, "/dev/zero", 0))
60 mem_info
.blocks
[0].size
= REAL_MEM_SIZE
;
61 mem_info
.blocks
[0].free
= 1;
66 static void real_mem_deinit(void)
69 munmap((void *)REAL_MEM_BASE
, REAL_MEM_SIZE
);
74 static void insert_block(int i
)
76 memmove(mem_info
.blocks
+ i
+ 1, mem_info
.blocks
+ i
,
77 (mem_info
.count
- i
) * sizeof(struct mem_block
));
81 static void delete_block(int i
)
84 memmove(mem_info
.blocks
+ i
, mem_info
.blocks
+ i
+ 1,
85 (mem_info
.count
- i
) * sizeof(struct mem_block
));
88 void *v86_mem_alloc(int size
)
91 char *r
= (char *)REAL_MEM_BASE
;
96 if (mem_info
.count
== REAL_MEM_BLOCKS
)
99 size
= (size
+ 15) & ~15;
101 for (i
= 0; i
< mem_info
.count
; i
++) {
102 if (mem_info
.blocks
[i
].free
&& size
< mem_info
.blocks
[i
].size
) {
105 mem_info
.blocks
[i
].size
= size
;
106 mem_info
.blocks
[i
].free
= 0;
107 mem_info
.blocks
[i
+ 1].size
-= size
;
112 r
+= mem_info
.blocks
[i
].size
;
118 void v86_mem_free(void *m
)
121 char *r
= (char *)REAL_MEM_BASE
;
127 while (m
!= (void *)r
) {
128 r
+= mem_info
.blocks
[i
].size
;
130 if (i
== mem_info
.count
)
134 mem_info
.blocks
[i
].free
= 1;
136 if (i
+ 1 < mem_info
.count
&& mem_info
.blocks
[i
+ 1].free
) {
137 mem_info
.blocks
[i
].size
+= mem_info
.blocks
[i
+ 1].size
;
141 if (i
- 1 >= 0 && mem_info
.blocks
[i
- 1].free
) {
142 mem_info
.blocks
[i
- 1].size
+= mem_info
.blocks
[i
].size
;
147 static inline void set_bit(unsigned int bit
, void *array
)
149 unsigned char *a
= array
;
150 a
[bit
/ 8] |= (1 << (bit
% 8));
153 inline u16
get_int_seg(int i
)
155 return *(u16
*)(uptr
)(i
* 4 + 2);
158 inline u16
get_int_off(int i
)
160 return *(u16
*)(uptr
)(i
* 4);
163 int v86_mem_init(void)
169 * We have to map the IVTBDA as shared. Without it, setting video
170 * modes will not work correctly on some cards (e.g. nVidia GeForce
173 if (!map_file((void *)IVTBDA_BASE
, IVTBDA_SIZE
,
174 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
175 MAP_FIXED
| MAP_SHARED
, "/dev/mem", 0))
181 if (!map_file((void *)0xa0000, MEM_SIZE
- 0xa0000,
182 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
183 MAP_FIXED
| MAP_SHARED
, "/dev/mem", 0xa0000))
185 munmap((void *)IVTBDA_BASE
, IVTBDA_SIZE
);
193 void v86_mem_cleanup(void)
195 munmap((void *)IVTBDA_BASE
, IVTBDA_SIZE
);
196 munmap((void *)0xa0000, MEM_SIZE
- 0xa0000);