PCem

view src/x86_ops_mov_seg.h @ 143:8523e78e0e48

Fixed default selector in instruction following MOV SS instruction, fixes Windows 3.1 installer
author TomW
date Sat Aug 16 17:36:50 2014 +0100
parents bd46c39a78e8
children
line source
1 static int opMOV_w_seg_a16(uint32_t fetchdat)
2 {
3 fetch_ea_16(fetchdat);
5 switch (rmdat & 0x38)
6 {
7 case 0x00: /*ES*/
8 seteaw(ES);
9 break;
10 case 0x08: /*CS*/
11 seteaw(CS);
12 break;
13 case 0x18: /*DS*/
14 seteaw(DS);
15 break;
16 case 0x10: /*SS*/
17 seteaw(SS);
18 break;
19 case 0x20: /*FS*/
20 seteaw(FS);
21 break;
22 case 0x28: /*GS*/
23 seteaw(GS);
24 break;
25 }
27 cycles -= ((mod == 3) ? 2 : 3);
28 return 0;
29 }
30 static int opMOV_w_seg_a32(uint32_t fetchdat)
31 {
32 fetch_ea_32(fetchdat);
34 switch (rmdat & 0x38)
35 {
36 case 0x00: /*ES*/
37 seteaw(ES);
38 break;
39 case 0x08: /*CS*/
40 seteaw(CS);
41 break;
42 case 0x18: /*DS*/
43 seteaw(DS);
44 break;
45 case 0x10: /*SS*/
46 seteaw(SS);
47 break;
48 case 0x20: /*FS*/
49 seteaw(FS);
50 break;
51 case 0x28: /*GS*/
52 seteaw(GS);
53 break;
54 }
56 cycles -= ((mod == 3) ? 2 : 3);
57 return 0;
58 }
60 static int opMOV_l_seg_a16(uint32_t fetchdat)
61 {
62 fetch_ea_16(fetchdat);
64 switch (rmdat & 0x38)
65 {
66 case 0x00: /*ES*/
67 if (mod == 3) regs[rm].l = ES;
68 else seteaw(ES);
69 break;
70 case 0x08: /*CS*/
71 if (mod == 3) regs[rm].l = CS;
72 else seteaw(CS);
73 break;
74 case 0x18: /*DS*/
75 if (mod == 3) regs[rm].l = DS;
76 else seteaw(DS);
77 break;
78 case 0x10: /*SS*/
79 if (mod == 3) regs[rm].l = SS;
80 else seteaw(SS);
81 break;
82 case 0x20: /*FS*/
83 if (mod == 3) regs[rm].l = FS;
84 else seteaw(FS);
85 break;
86 case 0x28: /*GS*/
87 if (mod == 3) regs[rm].l = GS;
88 else seteaw(GS);
89 break;
90 }
92 cycles -= ((mod == 3) ? 2 : 3);
93 return 0;
94 }
95 static int opMOV_l_seg_a32(uint32_t fetchdat)
96 {
97 fetch_ea_32(fetchdat);
99 switch (rmdat & 0x38)
100 {
101 case 0x00: /*ES*/
102 if (mod == 3) regs[rm].l = ES;
103 else seteaw(ES);
104 break;
105 case 0x08: /*CS*/
106 if (mod == 3) regs[rm].l = CS;
107 else seteaw(CS);
108 break;
109 case 0x18: /*DS*/
110 if (mod == 3) regs[rm].l = DS;
111 else seteaw(DS);
112 break;
113 case 0x10: /*SS*/
114 if (mod == 3) regs[rm].l = SS;
115 else seteaw(SS);
116 break;
117 case 0x20: /*FS*/
118 if (mod == 3) regs[rm].l = FS;
119 else seteaw(FS);
120 break;
121 case 0x28: /*GS*/
122 if (mod == 3) regs[rm].l = GS;
123 else seteaw(GS);
124 break;
125 }
127 cycles -= ((mod == 3) ? 2 : 3);
128 return 0;
129 }
131 static int opMOV_seg_w_a16(uint32_t fetchdat)
132 {
133 uint16_t new_seg;
135 fetch_ea_16(fetchdat);
137 new_seg=geteaw(); if (abrt) return 0;
139 switch (rmdat & 0x38)
140 {
141 case 0x00: /*ES*/
142 loadseg(new_seg, &_es);
143 break;
144 case 0x18: /*DS*/
145 loadseg(new_seg, &_ds);
146 break;
147 case 0x10: /*SS*/
148 loadseg(new_seg, &_ss);
149 if (abrt) return 0;
150 oldpc = pc;
151 op32 = use32;
152 ssegs = 0;
153 ea_seg = &_ds;
154 return 1;
155 case 0x20: /*FS*/
156 loadseg(new_seg, &_fs);
157 break;
158 case 0x28: /*GS*/
159 loadseg(new_seg, &_gs);
160 break;
161 }
163 cycles -= ((mod == 3) ? 2 : 5);
164 return 0;
165 }
166 static int opMOV_seg_w_a32(uint32_t fetchdat)
167 {
168 uint16_t new_seg;
170 fetch_ea_32(fetchdat);
172 new_seg=geteaw(); if (abrt) return 0;
174 switch (rmdat & 0x38)
175 {
176 case 0x00: /*ES*/
177 loadseg(new_seg, &_es);
178 break;
179 case 0x18: /*DS*/
180 loadseg(new_seg, &_ds);
181 break;
182 case 0x10: /*SS*/
183 loadseg(new_seg, &_ss);
184 if (abrt) return 0;
185 oldpc = pc;
186 op32 = use32;
187 ssegs = 0;
188 ea_seg = &_ds;
189 return 1;
190 case 0x20: /*FS*/
191 loadseg(new_seg, &_fs);
192 break;
193 case 0x28: /*GS*/
194 loadseg(new_seg, &_gs);
195 break;
196 }
198 cycles -= ((mod == 3) ? 2 : 5);
199 return 0;
200 }
203 static int opLDS_w_a16(uint32_t fetchdat)
204 {
205 uint16_t addr, seg;
207 fetch_ea_16(fetchdat);
208 ILLEGAL_ON(mod == 3);
209 addr = readmemw(easeg, eaaddr);
210 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
211 loadseg(seg, &_ds); if (abrt) return 0;
212 regs[reg].w = addr;
214 cycles -= 7;
215 return 0;
216 }
217 static int opLDS_w_a32(uint32_t fetchdat)
218 {
219 uint16_t addr, seg;
221 fetch_ea_32(fetchdat);
222 ILLEGAL_ON(mod == 3);
223 addr = readmemw(easeg, eaaddr);
224 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
225 loadseg(seg, &_ds); if (abrt) return 0;
226 regs[reg].w = addr;
228 cycles -= 7;
229 return 0;
230 }
231 static int opLDS_l_a16(uint32_t fetchdat)
232 {
233 uint32_t addr;
234 uint16_t seg;
236 fetch_ea_16(fetchdat);
237 ILLEGAL_ON(mod == 3);
238 addr = readmeml(easeg, eaaddr);
239 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
240 loadseg(seg, &_ds); if (abrt) return 0;
241 regs[reg].l = addr;
243 cycles -= 7;
244 return 0;
245 }
246 static int opLDS_l_a32(uint32_t fetchdat)
247 {
248 uint32_t addr;
249 uint16_t seg;
251 fetch_ea_32(fetchdat);
252 ILLEGAL_ON(mod == 3);
253 addr = readmeml(easeg, eaaddr);
254 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
255 loadseg(seg, &_ds); if (abrt) return 0;
256 regs[reg].l = addr;
258 cycles -= 7;
259 return 0;
260 }
262 static int opLSS_w_a16(uint32_t fetchdat)
263 {
264 uint16_t addr, seg;
266 fetch_ea_16(fetchdat);
267 ILLEGAL_ON(mod == 3);
268 addr = readmemw(easeg, eaaddr);
269 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
270 loadseg(seg, &_ss); if (abrt) return 0;
271 regs[reg].w = addr;
273 cycles -= 7;
274 return 0;
275 }
276 static int opLSS_w_a32(uint32_t fetchdat)
277 {
278 uint16_t addr, seg;
280 fetch_ea_32(fetchdat);
281 ILLEGAL_ON(mod == 3);
282 addr = readmemw(easeg, eaaddr);
283 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0;
284 loadseg(seg, &_ss); if (abrt) return 0;
285 regs[reg].w = addr;
287 cycles -= 7;
288 return 0;
289 }
290 static int opLSS_l_a16(uint32_t fetchdat)
291 {
292 uint32_t addr;
293 uint16_t seg;
295 fetch_ea_16(fetchdat);
296 ILLEGAL_ON(mod == 3);
297 addr = readmeml(easeg, eaaddr);
298 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
299 loadseg(seg, &_ss); if (abrt) return 0;
300 regs[reg].l = addr;
302 cycles -= 7;
303 return 0;
304 }
305 static int opLSS_l_a32(uint32_t fetchdat)
306 {
307 uint32_t addr;
308 uint16_t seg;
310 fetch_ea_32(fetchdat);
311 ILLEGAL_ON(mod == 3);
312 addr = readmeml(easeg, eaaddr);
313 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0;
314 loadseg(seg, &_ss); if (abrt) return 0;
315 regs[reg].l = addr;
317 cycles -= 7;
318 return 0;
319 }
321 #define opLsel(name, sel) \
322 static int opL ## name ## _w_a16(uint32_t fetchdat) \
323 { \
324 uint16_t addr, seg; \
325 \
326 fetch_ea_16(fetchdat); \
327 ILLEGAL_ON(mod == 3); \
328 addr = readmemw(easeg, eaaddr); \
329 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \
330 loadseg(seg, &sel); if (abrt) return 0; \
331 regs[reg].w = addr; \
332 \
333 cycles -= 7; \
334 return 0; \
335 } \
336 \
337 static int opL ## name ## _w_a32(uint32_t fetchdat) \
338 { \
339 uint16_t addr, seg; \
340 \
341 fetch_ea_32(fetchdat); \
342 ILLEGAL_ON(mod == 3); \
343 addr = readmemw(easeg, eaaddr); \
344 seg = readmemw(easeg, eaaddr + 2); if (abrt) return 0; \
345 loadseg(seg, &sel); if (abrt) return 0; \
346 regs[reg].w = addr; \
347 \
348 cycles -= 7; \
349 return 0; \
350 } \
351 \
352 static int opL ## name ## _l_a16(uint32_t fetchdat) \
353 { \
354 uint32_t addr; \
355 uint16_t seg; \
356 \
357 fetch_ea_16(fetchdat); \
358 ILLEGAL_ON(mod == 3); \
359 addr = readmeml(easeg, eaaddr); \
360 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \
361 loadseg(seg, &sel); if (abrt) return 0; \
362 regs[reg].l = addr; \
363 \
364 cycles -= 7; \
365 return 0; \
366 } \
367 \
368 static int opL ## name ## _l_a32(uint32_t fetchdat) \
369 { \
370 uint32_t addr; \
371 uint16_t seg; \
372 \
373 fetch_ea_32(fetchdat); \
374 ILLEGAL_ON(mod == 3); \
375 addr = readmeml(easeg, eaaddr); \
376 seg = readmemw(easeg, eaaddr + 4); if (abrt) return 0; \
377 loadseg(seg, &sel); if (abrt) return 0; \
378 regs[reg].l = addr; \
379 \
380 cycles -= 7; \
381 return 0; \
382 }
384 opLsel(ES, _es)
385 opLsel(FS, _fs)
386 opLsel(GS, _gs)