annotate linux/lrmi.c @ 8347:03ee1d7deba5

PSNR
author michael
date Wed, 04 Dec 2002 21:46:53 +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