annotate osdep/lrmi.c @ 11511:6e580b901205

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