annotate linux/lrmi.c @ 7492:5465cbd5c5ef

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