annotate osdep/lrmi.c @ 15151:1edaf17d5205

messed ordering of switch branches, 10l for Ivan
author henry
date Wed, 13 Apr 2005 19:38:44 +0000
parents 7a6d3ca86409
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
1 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
2 Linux Real Mode Interface - A library of DPMI-like functions for Linux.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
3
f0f681ef92ff LRMI import
nick
parents:
diff changeset
4 Copyright (C) 1998 by Josh Vanderhoof
f0f681ef92ff LRMI import
nick
parents:
diff changeset
5
f0f681ef92ff LRMI import
nick
parents:
diff changeset
6 You are free to distribute and modify this file, as long as you
f0f681ef92ff LRMI import
nick
parents:
diff changeset
7 do not remove this copyright notice and clearly label modified
f0f681ef92ff LRMI import
nick
parents:
diff changeset
8 versions as being modified.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
9
f0f681ef92ff LRMI import
nick
parents:
diff changeset
10 This software has NO WARRANTY. Use it at your own risk.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
11 Original location: http://cvs.debian.org/lrmi/
11795
7a6d3ca86409 Modification statement added.
diego
parents: 11519
diff changeset
12
7a6d3ca86409 Modification statement added.
diego
parents: 11519
diff changeset
13 Modified for use with MPlayer, see the CVS log for details.
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
14 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
15
11455
22f8732b5d97 cumulative libc5 compatibility patch ;)
gabucino
parents: 11434
diff changeset
16 #include "../config.h"
22f8732b5d97 cumulative libc5 compatibility patch ;)
gabucino
parents: 11434
diff changeset
17 #ifdef HAVE_VESA
22f8732b5d97 cumulative libc5 compatibility patch ;)
gabucino
parents: 11434
diff changeset
18
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
19 #include <signal.h>
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
20 #include <stdio.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
21 #include <string.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
22 #include <sys/io.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
23 #include <asm/vm86.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
24
f0f681ef92ff LRMI import
nick
parents:
diff changeset
25 #ifdef USE_LIBC_VM86
f0f681ef92ff LRMI import
nick
parents:
diff changeset
26 #include <sys/vm86.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
27 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
28
f0f681ef92ff LRMI import
nick
parents:
diff changeset
29 #include <sys/types.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
30 #include <sys/stat.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
31 #include <sys/mman.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
32 #include <unistd.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
33 #include <fcntl.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
34
f0f681ef92ff LRMI import
nick
parents:
diff changeset
35 #include "lrmi.h"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
36
f0f681ef92ff LRMI import
nick
parents:
diff changeset
37 #define REAL_MEM_BASE ((void *)0x10000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
38 #define REAL_MEM_SIZE 0x10000
f0f681ef92ff LRMI import
nick
parents:
diff changeset
39 #define REAL_MEM_BLOCKS 0x100
f0f681ef92ff LRMI import
nick
parents:
diff changeset
40
f0f681ef92ff LRMI import
nick
parents:
diff changeset
41 struct mem_block
f0f681ef92ff LRMI import
nick
parents:
diff changeset
42 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
43 unsigned int size : 20;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
44 unsigned int free : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
45 };
f0f681ef92ff LRMI import
nick
parents:
diff changeset
46
f0f681ef92ff LRMI import
nick
parents:
diff changeset
47 static struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
48 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
49 int ready;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
50 int count;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
51 struct mem_block blocks[REAL_MEM_BLOCKS];
10857
608666e629b2 warning fix (missing C initializer)
pl
parents: 9380
diff changeset
52 } mem_info = { .ready = 0, };
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
53
f0f681ef92ff LRMI import
nick
parents:
diff changeset
54 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
55 real_mem_init(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
56 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
57 void *m;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
58 int fd_zero;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
59
f0f681ef92ff LRMI import
nick
parents:
diff changeset
60 if (mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
61 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
62
f0f681ef92ff LRMI import
nick
parents:
diff changeset
63 fd_zero = open("/dev/zero", O_RDONLY);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
64 if (fd_zero == -1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
65 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
66 perror("open /dev/zero");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
67 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
68 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
69
f0f681ef92ff LRMI import
nick
parents:
diff changeset
70 m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
71 PROT_READ | PROT_WRITE | PROT_EXEC,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
72 MAP_FIXED | MAP_PRIVATE, fd_zero, 0);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
73
f0f681ef92ff LRMI import
nick
parents:
diff changeset
74 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
75 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
76 perror("mmap /dev/zero");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
77 close(fd_zero);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
78 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
79 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
80
f0f681ef92ff LRMI import
nick
parents:
diff changeset
81 mem_info.ready = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
82 mem_info.count = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
83 mem_info.blocks[0].size = REAL_MEM_SIZE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
84 mem_info.blocks[0].free = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
85
f0f681ef92ff LRMI import
nick
parents:
diff changeset
86 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
87 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
88
f0f681ef92ff LRMI import
nick
parents:
diff changeset
89
f0f681ef92ff LRMI import
nick
parents:
diff changeset
90 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
91 insert_block(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
92 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
93 memmove(
f0f681ef92ff LRMI import
nick
parents:
diff changeset
94 mem_info.blocks + i + 1,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
95 mem_info.blocks + i,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
96 (mem_info.count - i) * sizeof(struct mem_block));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
97
f0f681ef92ff LRMI import
nick
parents:
diff changeset
98 mem_info.count++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
99 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
100
f0f681ef92ff LRMI import
nick
parents:
diff changeset
101 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
102 delete_block(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
103 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
104 mem_info.count--;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
105
f0f681ef92ff LRMI import
nick
parents:
diff changeset
106 memmove(
f0f681ef92ff LRMI import
nick
parents:
diff changeset
107 mem_info.blocks + i,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
108 mem_info.blocks + i + 1,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
109 (mem_info.count - i) * sizeof(struct mem_block));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
110 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
111
f0f681ef92ff LRMI import
nick
parents:
diff changeset
112 void *
f0f681ef92ff LRMI import
nick
parents:
diff changeset
113 LRMI_alloc_real(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
114 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
115 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
116 char *r = (char *)REAL_MEM_BASE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
117
f0f681ef92ff LRMI import
nick
parents:
diff changeset
118 if (!mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
119 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
120
f0f681ef92ff LRMI import
nick
parents:
diff changeset
121 if (mem_info.count == REAL_MEM_BLOCKS)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
122 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
123
f0f681ef92ff LRMI import
nick
parents:
diff changeset
124 size = (size + 15) & ~15;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
125
f0f681ef92ff LRMI import
nick
parents:
diff changeset
126 for (i = 0; i < mem_info.count; i++)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
127 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
128 if (mem_info.blocks[i].free && size < mem_info.blocks[i].size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
129 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
130 insert_block(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
131
f0f681ef92ff LRMI import
nick
parents:
diff changeset
132 mem_info.blocks[i].size = size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
133 mem_info.blocks[i].free = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
134 mem_info.blocks[i + 1].size -= size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
135
f0f681ef92ff LRMI import
nick
parents:
diff changeset
136 return (void *)r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
137 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
138
f0f681ef92ff LRMI import
nick
parents:
diff changeset
139 r += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
140 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
141
f0f681ef92ff LRMI import
nick
parents:
diff changeset
142 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
143 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
144
f0f681ef92ff LRMI import
nick
parents:
diff changeset
145
f0f681ef92ff LRMI import
nick
parents:
diff changeset
146 void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
147 LRMI_free_real(void *m)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
148 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
149 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
150 char *r = (char *)REAL_MEM_BASE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
151
f0f681ef92ff LRMI import
nick
parents:
diff changeset
152 if (!mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
153 return;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
154
f0f681ef92ff LRMI import
nick
parents:
diff changeset
155 i = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
156 while (m != (void *)r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
157 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
158 r += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
159 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
160 if (i == mem_info.count)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
161 return;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
162 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
163
f0f681ef92ff LRMI import
nick
parents:
diff changeset
164 mem_info.blocks[i].free = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
165
f0f681ef92ff LRMI import
nick
parents:
diff changeset
166 if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
167 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
168 mem_info.blocks[i].size += mem_info.blocks[i + 1].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
169 delete_block(i + 1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
170 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
171
f0f681ef92ff LRMI import
nick
parents:
diff changeset
172 if (i - 1 >= 0 && mem_info.blocks[i - 1].free)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
173 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
174 mem_info.blocks[i - 1].size += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
175 delete_block(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
176 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
177 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
178
f0f681ef92ff LRMI import
nick
parents:
diff changeset
179
f0f681ef92ff LRMI import
nick
parents:
diff changeset
180 #define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
181 #define DEFAULT_STACK_SIZE 0x1000
f0f681ef92ff LRMI import
nick
parents:
diff changeset
182 #define RETURN_TO_32_INT 255
f0f681ef92ff LRMI import
nick
parents:
diff changeset
183
f0f681ef92ff LRMI import
nick
parents:
diff changeset
184 static struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
185 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
186 int ready;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
187 unsigned short ret_seg, ret_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
188 unsigned short stack_seg, stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
189 struct vm86_struct vm;
10857
608666e629b2 warning fix (missing C initializer)
pl
parents: 9380
diff changeset
190 } context = { .ready = 0, };
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
191
f0f681ef92ff LRMI import
nick
parents:
diff changeset
192
f0f681ef92ff LRMI import
nick
parents:
diff changeset
193 static inline void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
194 set_bit(unsigned int bit, void *array)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
195 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
196 unsigned char *a = array;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
197
f0f681ef92ff LRMI import
nick
parents:
diff changeset
198 a[bit / 8] |= (1 << (bit % 8));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
199 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
200
f0f681ef92ff LRMI import
nick
parents:
diff changeset
201
f0f681ef92ff LRMI import
nick
parents:
diff changeset
202 static inline unsigned int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
203 get_int_seg(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
204 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
205 return *(unsigned short *)(i * 4 + 2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
206 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
207
f0f681ef92ff LRMI import
nick
parents:
diff changeset
208
f0f681ef92ff LRMI import
nick
parents:
diff changeset
209 static inline unsigned int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
210 get_int_off(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
211 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
212 return *(unsigned short *)(i * 4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
213 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
214
f0f681ef92ff LRMI import
nick
parents:
diff changeset
215
f0f681ef92ff LRMI import
nick
parents:
diff changeset
216 static inline void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
217 pushw(unsigned short i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
218 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
219 struct vm86_regs *r = &context.vm.regs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
220 r->esp -= 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
221 *(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
222 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
223
f0f681ef92ff LRMI import
nick
parents:
diff changeset
224
f0f681ef92ff LRMI import
nick
parents:
diff changeset
225 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
226 LRMI_init(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
227 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
228 void *m;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
229 int fd_mem;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
230
f0f681ef92ff LRMI import
nick
parents:
diff changeset
231 if (context.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
232 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
233
f0f681ef92ff LRMI import
nick
parents:
diff changeset
234 if (!real_mem_init())
f0f681ef92ff LRMI import
nick
parents:
diff changeset
235 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
236
f0f681ef92ff LRMI import
nick
parents:
diff changeset
237 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
238 Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
239 and the ROM (0xa0000 - 0x100000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
240 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
241 fd_mem = open("/dev/mem", O_RDWR);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
242
f0f681ef92ff LRMI import
nick
parents:
diff changeset
243 if (fd_mem == -1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
244 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
245 perror("open /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
246 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
247 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
248
f0f681ef92ff LRMI import
nick
parents:
diff changeset
249 m = mmap((void *)0, 0x502,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
250 PROT_READ | PROT_WRITE | PROT_EXEC,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
251 MAP_FIXED | MAP_PRIVATE, fd_mem, 0);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
252
f0f681ef92ff LRMI import
nick
parents:
diff changeset
253 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
254 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
255 perror("mmap /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
256 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
257 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
258
f0f681ef92ff LRMI import
nick
parents:
diff changeset
259 m = mmap((void *)0xa0000, 0x100000 - 0xa0000,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
260 PROT_READ | PROT_WRITE,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
261 MAP_FIXED | MAP_SHARED, fd_mem, 0xa0000);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
262
f0f681ef92ff LRMI import
nick
parents:
diff changeset
263 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
264 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
265 perror("mmap /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
266 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
267 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
268
f0f681ef92ff LRMI import
nick
parents:
diff changeset
269
f0f681ef92ff LRMI import
nick
parents:
diff changeset
270 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
271 Allocate a stack
f0f681ef92ff LRMI import
nick
parents:
diff changeset
272 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
273 m = LRMI_alloc_real(DEFAULT_STACK_SIZE);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
274
f0f681ef92ff LRMI import
nick
parents:
diff changeset
275 context.stack_seg = (unsigned int)m >> 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
276 context.stack_off = DEFAULT_STACK_SIZE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
277
f0f681ef92ff LRMI import
nick
parents:
diff changeset
278 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
279 Allocate the return to 32 bit routine
f0f681ef92ff LRMI import
nick
parents:
diff changeset
280 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
281 m = LRMI_alloc_real(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
282
f0f681ef92ff LRMI import
nick
parents:
diff changeset
283 context.ret_seg = (unsigned int)m >> 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
284 context.ret_off = (unsigned int)m & 0xf;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
285
f0f681ef92ff LRMI import
nick
parents:
diff changeset
286 ((unsigned char *)m)[0] = 0xcd; /* int opcode */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
287 ((unsigned char *)m)[1] = RETURN_TO_32_INT;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
288
f0f681ef92ff LRMI import
nick
parents:
diff changeset
289 memset(&context.vm, 0, sizeof(context.vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
290
f0f681ef92ff LRMI import
nick
parents:
diff changeset
291 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
292 Enable kernel emulation of all ints except RETURN_TO_32_INT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
293 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
294 memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
295 set_bit(RETURN_TO_32_INT, &context.vm.int_revectored);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
296
f0f681ef92ff LRMI import
nick
parents:
diff changeset
297 context.ready = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
298
f0f681ef92ff LRMI import
nick
parents:
diff changeset
299 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
300 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
301
f0f681ef92ff LRMI import
nick
parents:
diff changeset
302
f0f681ef92ff LRMI import
nick
parents:
diff changeset
303 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
304 set_regs(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
305 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
306 context.vm.regs.edi = r->edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
307 context.vm.regs.esi = r->esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
308 context.vm.regs.ebp = r->ebp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
309 context.vm.regs.ebx = r->ebx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
310 context.vm.regs.edx = r->edx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
311 context.vm.regs.ecx = r->ecx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
312 context.vm.regs.eax = r->eax;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
313 context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
314 context.vm.regs.es = r->es;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
315 context.vm.regs.ds = r->ds;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
316 context.vm.regs.fs = r->fs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
317 context.vm.regs.gs = r->gs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
318 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
319
f0f681ef92ff LRMI import
nick
parents:
diff changeset
320
f0f681ef92ff LRMI import
nick
parents:
diff changeset
321 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
322 get_regs(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
323 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
324 r->edi = context.vm.regs.edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
325 r->esi = context.vm.regs.esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
326 r->ebp = context.vm.regs.ebp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
327 r->ebx = context.vm.regs.ebx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
328 r->edx = context.vm.regs.edx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
329 r->ecx = context.vm.regs.ecx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
330 r->eax = context.vm.regs.eax;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
331 r->flags = context.vm.regs.eflags;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
332 r->es = context.vm.regs.es;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
333 r->ds = context.vm.regs.ds;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
334 r->fs = context.vm.regs.fs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
335 r->gs = context.vm.regs.gs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
336 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
337
f0f681ef92ff LRMI import
nick
parents:
diff changeset
338 #define DIRECTION_FLAG (1 << 10)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
339
f0f681ef92ff LRMI import
nick
parents:
diff changeset
340 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
341 em_ins(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
342 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
343 unsigned int edx, edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
344
f0f681ef92ff LRMI import
nick
parents:
diff changeset
345 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
346 edi = context.vm.regs.edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
347 edi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
348
f0f681ef92ff LRMI import
nick
parents:
diff changeset
349 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
350 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
351 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
352 asm volatile ("std; insl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
353 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
354 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
355 asm volatile ("std; insw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
356 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
357 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
358 asm volatile ("std; insb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
359 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
360 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
361 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
362 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
363 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
364 asm volatile ("cld; insl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
365 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
366 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
367 asm volatile ("cld; insw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
368 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
369 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
370 asm volatile ("cld; insb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
371 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
372 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
373
f0f681ef92ff LRMI import
nick
parents:
diff changeset
374 edi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
375
f0f681ef92ff LRMI import
nick
parents:
diff changeset
376 context.vm.regs.edi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
377 context.vm.regs.edi |= edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
378 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
379
f0f681ef92ff LRMI import
nick
parents:
diff changeset
380 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
381 em_rep_ins(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
382 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
383 unsigned int ecx, edx, edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
384
f0f681ef92ff LRMI import
nick
parents:
diff changeset
385 ecx = context.vm.regs.ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
386 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
387 edi = context.vm.regs.edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
388 edi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
389
f0f681ef92ff LRMI import
nick
parents:
diff changeset
390 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
391 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
392 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
393 asm volatile ("std; rep; insl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
394 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
395 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
396 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
397 asm volatile ("std; rep; insw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
398 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
399 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
400 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
401 asm volatile ("std; rep; insb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
402 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
403 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
404 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
405 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
406 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
407 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
408 asm volatile ("cld; rep; insl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
409 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
410 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
411 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
412 asm volatile ("cld; rep; insw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
413 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
414 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
415 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
416 asm volatile ("cld; rep; insb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
417 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
418 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
419 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
420
f0f681ef92ff LRMI import
nick
parents:
diff changeset
421 edi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
422
f0f681ef92ff LRMI import
nick
parents:
diff changeset
423 context.vm.regs.edi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
424 context.vm.regs.edi |= edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
425
f0f681ef92ff LRMI import
nick
parents:
diff changeset
426 context.vm.regs.ecx &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
427 context.vm.regs.ecx |= ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
428 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
429
f0f681ef92ff LRMI import
nick
parents:
diff changeset
430 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
431 em_outs(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
432 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
433 unsigned int edx, esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
434
f0f681ef92ff LRMI import
nick
parents:
diff changeset
435 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
436 esi = context.vm.regs.esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
437 esi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
438
f0f681ef92ff LRMI import
nick
parents:
diff changeset
439 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
440 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
441 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
442 asm volatile ("std; outsl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
443 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
444 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
445 asm volatile ("std; outsw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
446 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
447 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
448 asm volatile ("std; outsb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
449 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
450 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
451 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
452 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
453 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
454 asm volatile ("cld; outsl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
455 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
456 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
457 asm volatile ("cld; outsw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
458 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
459 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
460 asm volatile ("cld; outsb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
461 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
462 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
463
f0f681ef92ff LRMI import
nick
parents:
diff changeset
464 esi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
465
f0f681ef92ff LRMI import
nick
parents:
diff changeset
466 context.vm.regs.esi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
467 context.vm.regs.esi |= esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
468 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
469
f0f681ef92ff LRMI import
nick
parents:
diff changeset
470 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
471 em_rep_outs(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
472 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
473 unsigned int ecx, edx, esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
474
f0f681ef92ff LRMI import
nick
parents:
diff changeset
475 ecx = context.vm.regs.ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
476 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
477 esi = context.vm.regs.esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
478 esi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
479
f0f681ef92ff LRMI import
nick
parents:
diff changeset
480 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
481 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
482 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
483 asm volatile ("std; rep; outsl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
484 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
485 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
486 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
487 asm volatile ("std; rep; outsw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
488 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
489 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
490 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
491 asm volatile ("std; rep; outsb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
492 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
493 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
494 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
495 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
496 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
497 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
498 asm volatile ("cld; rep; outsl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
499 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
500 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
501 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
502 asm volatile ("cld; rep; outsw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
503 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
504 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
505 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
506 asm volatile ("cld; rep; outsb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
507 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
508 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
509 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
510
f0f681ef92ff LRMI import
nick
parents:
diff changeset
511 esi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
512
f0f681ef92ff LRMI import
nick
parents:
diff changeset
513 context.vm.regs.esi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
514 context.vm.regs.esi |= esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
515
f0f681ef92ff LRMI import
nick
parents:
diff changeset
516 context.vm.regs.ecx &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
517 context.vm.regs.ecx |= ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
518 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
519
f0f681ef92ff LRMI import
nick
parents:
diff changeset
520 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
521 em_inbl(unsigned char literal)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
522 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
523 context.vm.regs.eax = inb(literal) & 0xff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
524 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
525
f0f681ef92ff LRMI import
nick
parents:
diff changeset
526 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
527 em_inb(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
528 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
529 asm volatile ("inb (%w1), %b0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
530 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
531 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
532 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
533
f0f681ef92ff LRMI import
nick
parents:
diff changeset
534 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
535 em_inw(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
536 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
537 asm volatile ("inw (%w1), %w0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
538 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
539 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
540 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
541
f0f681ef92ff LRMI import
nick
parents:
diff changeset
542 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
543 em_inl(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
544 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
545 asm volatile ("inl (%w1), %0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
546 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
547 : "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
548 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
549
f0f681ef92ff LRMI import
nick
parents:
diff changeset
550 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
551 em_outbl(unsigned char literal)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
552 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
553 outb(context.vm.regs.eax & 0xff, literal);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
554 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
555
f0f681ef92ff LRMI import
nick
parents:
diff changeset
556 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
557 em_outb(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
558 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
559 asm volatile ("outb %b0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
560 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
561 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
562 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
563
f0f681ef92ff LRMI import
nick
parents:
diff changeset
564 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
565 em_outw(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
566 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
567 asm volatile ("outw %w0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
568 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
569 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
570 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
571
f0f681ef92ff LRMI import
nick
parents:
diff changeset
572 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
573 em_outl(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
574 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
575 asm volatile ("outl %0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
576 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
577 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
578 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
579
f0f681ef92ff LRMI import
nick
parents:
diff changeset
580 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
581 emulate(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
582 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
583 unsigned char *insn;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
584 struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
585 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
586 unsigned int size : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
587 unsigned int rep : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
588 } prefix = { 0, 0 };
f0f681ef92ff LRMI import
nick
parents:
diff changeset
589 int i = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
590
f0f681ef92ff LRMI import
nick
parents:
diff changeset
591 insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
592 insn += context.vm.regs.eip;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
593
f0f681ef92ff LRMI import
nick
parents:
diff changeset
594 while (1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
595 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
596 if (insn[i] == 0x66)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
597 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
598 prefix.size = 1 - prefix.size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
599 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
600 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
601 else if (insn[i] == 0xf3)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
602 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
603 prefix.rep = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
604 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
605 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
606 else if (insn[i] == 0xf0 || insn[i] == 0xf2
f0f681ef92ff LRMI import
nick
parents:
diff changeset
607 || insn[i] == 0x26 || insn[i] == 0x2e
f0f681ef92ff LRMI import
nick
parents:
diff changeset
608 || insn[i] == 0x36 || insn[i] == 0x3e
f0f681ef92ff LRMI import
nick
parents:
diff changeset
609 || insn[i] == 0x64 || insn[i] == 0x65
f0f681ef92ff LRMI import
nick
parents:
diff changeset
610 || insn[i] == 0x67)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
611 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
612 /* these prefixes are just ignored */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
613 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
614 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
615 else if (insn[i] == 0x6c)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
616 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
617 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
618 em_rep_ins(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
619 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
620 em_ins(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
621 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
622 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
623 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
624 else if (insn[i] == 0x6d)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
625 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
626 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
627 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
628 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
629 em_rep_ins(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
630 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
631 em_rep_ins(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
632 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
633 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
634 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
635 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
636 em_ins(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
637 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
638 em_ins(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
639 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
640 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
641 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
642 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
643 else if (insn[i] == 0x6e)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
644 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
645 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
646 em_rep_outs(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
647 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
648 em_outs(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
649 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
650 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
651 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
652 else if (insn[i] == 0x6f)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
653 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
654 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
655 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
656 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
657 em_rep_outs(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
658 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
659 em_rep_outs(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
660 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
661 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
662 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
663 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
664 em_outs(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
665 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
666 em_outs(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
667 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
668 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
669 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
670 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
671 else if (insn[i] == 0xe4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
672 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
673 em_inbl(insn[i + 1]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
674 i += 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
675 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
676 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
677 else if (insn[i] == 0xe6)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
678 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
679 em_outbl(insn[i + 1]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
680 i += 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
681 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
682 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
683 else if (insn[i] == 0xec)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
684 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
685 em_inb();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
686 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
687 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
688 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
689 else if (insn[i] == 0xed)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
690 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
691 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
692 em_inl();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
693 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
694 em_inw();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
695 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
696 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
697 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
698 else if (insn[i] == 0xee)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
699 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
700 em_outb();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
701 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
702 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
703 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
704 else if (insn[i] == 0xef)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
705 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
706 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
707 em_outl();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
708 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
709 em_outw();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
710
f0f681ef92ff LRMI import
nick
parents:
diff changeset
711 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
712 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
713 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
714 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
715 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
716 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
717
f0f681ef92ff LRMI import
nick
parents:
diff changeset
718 context.vm.regs.eip += i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
719 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
720 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
721
f0f681ef92ff LRMI import
nick
parents:
diff changeset
722
f0f681ef92ff LRMI import
nick
parents:
diff changeset
723 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
724 I don't know how to make sure I get the right vm86() from libc.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
725 The one I want is syscall # 113 (vm86old() in libc 5, vm86() in glibc)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
726 which should be declared as "int vm86(struct vm86_struct *);" in
f0f681ef92ff LRMI import
nick
parents:
diff changeset
727 <sys/vm86.h>.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
728
f0f681ef92ff LRMI import
nick
parents:
diff changeset
729 This just does syscall 113 with inline asm, which should work
f0f681ef92ff LRMI import
nick
parents:
diff changeset
730 for both libc's (I hope).
f0f681ef92ff LRMI import
nick
parents:
diff changeset
731 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
732 #if !defined(USE_LIBC_VM86)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
733 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
734 lrmi_vm86(struct vm86_struct *vm)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
735 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
736 int r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
737 #ifdef __PIC__
f0f681ef92ff LRMI import
nick
parents:
diff changeset
738 asm volatile (
f0f681ef92ff LRMI import
nick
parents:
diff changeset
739 "pushl %%ebx\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
740 "movl %2, %%ebx\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
741 "int $0x80\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
742 "popl %%ebx"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
743 : "=a" (r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
744 : "0" (113), "r" (vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
745 #else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
746 asm volatile (
f0f681ef92ff LRMI import
nick
parents:
diff changeset
747 "int $0x80"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
748 : "=a" (r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
749 : "0" (113), "b" (vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
750 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
751 return r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
752 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
753 #else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
754 #define lrmi_vm86 vm86
f0f681ef92ff LRMI import
nick
parents:
diff changeset
755 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
756
f0f681ef92ff LRMI import
nick
parents:
diff changeset
757
f0f681ef92ff LRMI import
nick
parents:
diff changeset
758 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
759 debug_info(int vret)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
760 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
761 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
762 unsigned char *p;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
763
f0f681ef92ff LRMI import
nick
parents:
diff changeset
764 fputs("vm86() failed\n", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
765 fprintf(stderr, "return = 0x%x\n", vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
766 fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
767 fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
768 fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
769 fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
770 fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
771 fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
772 fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
773 fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
774 fprintf(stderr, "cs = 0x%04x\n", context.vm.regs.cs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
775 fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
776 fprintf(stderr, "ss = 0x%04x\n", context.vm.regs.ss);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
777 fprintf(stderr, "ds = 0x%04x\n", context.vm.regs.ds);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
778 fprintf(stderr, "es = 0x%04x\n", context.vm.regs.es);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
779 fprintf(stderr, "fs = 0x%04x\n", context.vm.regs.fs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
780 fprintf(stderr, "gs = 0x%04x\n", context.vm.regs.gs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
781 fprintf(stderr, "eflags = 0x%08lx\n", context.vm.regs.eflags);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
782
f0f681ef92ff LRMI import
nick
parents:
diff changeset
783 fputs("cs:ip = [ ", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
784
f0f681ef92ff LRMI import
nick
parents:
diff changeset
785 p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
786
f0f681ef92ff LRMI import
nick
parents:
diff changeset
787 for (i = 0; i < 16; ++i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
788 fprintf(stderr, "%02x ", (unsigned int)p[i]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
789
f0f681ef92ff LRMI import
nick
parents:
diff changeset
790 fputs("]\n", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
791 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
792
f0f681ef92ff LRMI import
nick
parents:
diff changeset
793
f0f681ef92ff LRMI import
nick
parents:
diff changeset
794 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
795 run_vm86(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
796 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
797 unsigned int vret;
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
798 sigset_t allsigs, cursigs;
11519
830c5c1800bc Save fs before calling vm86, this might eleminate bugs (if there were any) in cooperation of using vesa with win32 dlls. Patch by Peter Kosinar <goober@ksp.sk>
alex
parents: 11455
diff changeset
799 unsigned long oldgs, oldfs;
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
800
f0f681ef92ff LRMI import
nick
parents:
diff changeset
801 while (1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
802 {
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
803 sigfillset(&allsigs);
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
804 sigprocmask(SIG_SETMASK, &allsigs, &cursigs);
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
805 asm volatile ("movl %%gs, %0" : "=g" (oldgs));
11519
830c5c1800bc Save fs before calling vm86, this might eleminate bugs (if there were any) in cooperation of using vesa with win32 dlls. Patch by Peter Kosinar <goober@ksp.sk>
alex
parents: 11455
diff changeset
806 asm volatile ("movl %%fs, %0" : "=g" (oldfs));
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
807 vret = lrmi_vm86(&context.vm);
11519
830c5c1800bc Save fs before calling vm86, this might eleminate bugs (if there were any) in cooperation of using vesa with win32 dlls. Patch by Peter Kosinar <goober@ksp.sk>
alex
parents: 11455
diff changeset
808 asm volatile ("movl %0, %%fs" :: "g" (oldfs));
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
809 asm volatile ("movl %0, %%gs" :: "g" (oldgs));
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
810 sigprocmask(SIG_SETMASK, &cursigs, NULL);
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
811
f0f681ef92ff LRMI import
nick
parents:
diff changeset
812 if (VM86_TYPE(vret) == VM86_INTx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
813 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
814 unsigned int v = VM86_ARG(vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
815
f0f681ef92ff LRMI import
nick
parents:
diff changeset
816 if (v == RETURN_TO_32_INT)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
817 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
818
f0f681ef92ff LRMI import
nick
parents:
diff changeset
819 pushw(context.vm.regs.eflags);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
820 pushw(context.vm.regs.cs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
821 pushw(context.vm.regs.eip);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
822
f0f681ef92ff LRMI import
nick
parents:
diff changeset
823 context.vm.regs.cs = get_int_seg(v);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
824 context.vm.regs.eip = get_int_off(v);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
825 context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
826
f0f681ef92ff LRMI import
nick
parents:
diff changeset
827 continue;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
828 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
829
f0f681ef92ff LRMI import
nick
parents:
diff changeset
830 if (VM86_TYPE(vret) != VM86_UNKNOWN)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
831 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
832
f0f681ef92ff LRMI import
nick
parents:
diff changeset
833 if (!emulate())
f0f681ef92ff LRMI import
nick
parents:
diff changeset
834 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
835 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
836
f0f681ef92ff LRMI import
nick
parents:
diff changeset
837 #ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
838 debug_info(vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
839 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
840 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
841 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
842
f0f681ef92ff LRMI import
nick
parents:
diff changeset
843
f0f681ef92ff LRMI import
nick
parents:
diff changeset
844 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
845 LRMI_call(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
846 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
847 unsigned int vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
848
f0f681ef92ff LRMI import
nick
parents:
diff changeset
849 memset(&context.vm.regs, 0, sizeof(context.vm.regs));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
850
f0f681ef92ff LRMI import
nick
parents:
diff changeset
851 set_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
852
f0f681ef92ff LRMI import
nick
parents:
diff changeset
853 context.vm.regs.cs = r->cs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
854 context.vm.regs.eip = r->ip;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
855
f0f681ef92ff LRMI import
nick
parents:
diff changeset
856 if (r->ss == 0 && r->sp == 0)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
857 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
858 context.vm.regs.ss = context.stack_seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
859 context.vm.regs.esp = context.stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
860 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
861 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
862 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
863 context.vm.regs.ss = r->ss;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
864 context.vm.regs.esp = r->sp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
865 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
866
f0f681ef92ff LRMI import
nick
parents:
diff changeset
867 pushw(context.ret_seg);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
868 pushw(context.ret_off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
869
f0f681ef92ff LRMI import
nick
parents:
diff changeset
870 vret = run_vm86();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
871
f0f681ef92ff LRMI import
nick
parents:
diff changeset
872 get_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
873
f0f681ef92ff LRMI import
nick
parents:
diff changeset
874 return vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
875 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
876
f0f681ef92ff LRMI import
nick
parents:
diff changeset
877
f0f681ef92ff LRMI import
nick
parents:
diff changeset
878 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
879 LRMI_int(int i, struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
880 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
881 unsigned int vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
882 unsigned int seg, off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
883
f0f681ef92ff LRMI import
nick
parents:
diff changeset
884 seg = get_int_seg(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
885 off = get_int_off(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
886
f0f681ef92ff LRMI import
nick
parents:
diff changeset
887 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
888 If the interrupt is in regular memory, it's probably
f0f681ef92ff LRMI import
nick
parents:
diff changeset
889 still pointing at a dos TSR (which is now gone).
f0f681ef92ff LRMI import
nick
parents:
diff changeset
890 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
891 if (seg < 0xa000 || (seg << 4) + off >= 0x100000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
892 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
893 #ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
894 fprintf(stderr, "Int 0x%x is not in rom (%04x:%04x)\n", i, seg, off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
895 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
896 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
897 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
898
f0f681ef92ff LRMI import
nick
parents:
diff changeset
899 memset(&context.vm.regs, 0, sizeof(context.vm.regs));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
900
f0f681ef92ff LRMI import
nick
parents:
diff changeset
901 set_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
902
f0f681ef92ff LRMI import
nick
parents:
diff changeset
903 context.vm.regs.cs = seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
904 context.vm.regs.eip = off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
905
f0f681ef92ff LRMI import
nick
parents:
diff changeset
906 if (r->ss == 0 && r->sp == 0)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
907 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
908 context.vm.regs.ss = context.stack_seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
909 context.vm.regs.esp = context.stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
910 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
911 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
912 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
913 context.vm.regs.ss = r->ss;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
914 context.vm.regs.esp = r->sp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
915 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
916
f0f681ef92ff LRMI import
nick
parents:
diff changeset
917 pushw(DEFAULT_VM86_FLAGS);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
918 pushw(context.ret_seg);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
919 pushw(context.ret_off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
920
f0f681ef92ff LRMI import
nick
parents:
diff changeset
921 vret = run_vm86();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
922
f0f681ef92ff LRMI import
nick
parents:
diff changeset
923 get_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
924
f0f681ef92ff LRMI import
nick
parents:
diff changeset
925 return vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
926 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
927
11455
22f8732b5d97 cumulative libc5 compatibility patch ;)
gabucino
parents: 11434
diff changeset
928 #endif