PCem
view src/x86_ops_mov.h @ 142:bd46c39a78e8
Implemented selector limits on some instructions - fixes LBA2.
GPFs in real mode now work.
Selectors correctly zeroed on far return to lower privilege.
| author | TomW |
|---|---|
| date | Wed Aug 13 20:33:56 2014 +0100 |
| parents | 9bc3bcf7c871 |
| children |
line source
1 static int opMOV_AL_imm(uint32_t fetchdat)
2 {
3 AL = getbytef();
4 cycles -= timing_rr;
5 return 0;
6 }
7 static int opMOV_AH_imm(uint32_t fetchdat)
8 {
9 AH = getbytef();
10 cycles -= timing_rr;
11 return 0;
12 }
13 static int opMOV_BL_imm(uint32_t fetchdat)
14 {
15 BL = getbytef();
16 cycles -= timing_rr;
17 return 0;
18 }
19 static int opMOV_BH_imm(uint32_t fetchdat)
20 {
21 BH = getbytef();
22 cycles -= timing_rr;
23 return 0;
24 }
25 static int opMOV_CL_imm(uint32_t fetchdat)
26 {
27 CL = getbytef();
28 cycles -= timing_rr;
29 return 0;
30 }
31 static int opMOV_CH_imm(uint32_t fetchdat)
32 {
33 CH = getbytef();
34 cycles -= timing_rr;
35 return 0;
36 }
37 static int opMOV_DL_imm(uint32_t fetchdat)
38 {
39 DL = getbytef();
40 cycles -= timing_rr;
41 return 0;
42 }
43 static int opMOV_DH_imm(uint32_t fetchdat)
44 {
45 DH = getbytef();
46 cycles -= timing_rr;
47 return 0;
48 }
50 static int opMOV_AX_imm(uint32_t fetchdat)
51 {
52 AX = getwordf();
53 cycles -= timing_rr;
54 return 0;
55 }
56 static int opMOV_BX_imm(uint32_t fetchdat)
57 {
58 BX = getwordf();
59 cycles -= timing_rr;
60 return 0;
61 }
62 static int opMOV_CX_imm(uint32_t fetchdat)
63 {
64 CX = getwordf();
65 cycles -= timing_rr;
66 return 0;
67 }
68 static int opMOV_DX_imm(uint32_t fetchdat)
69 {
70 DX = getwordf();
71 cycles -= timing_rr;
72 return 0;
73 }
74 static int opMOV_SI_imm(uint32_t fetchdat)
75 {
76 SI = getwordf();
77 cycles -= timing_rr;
78 return 0;
79 }
80 static int opMOV_DI_imm(uint32_t fetchdat)
81 {
82 DI = getwordf();
83 cycles -= timing_rr;
84 return 0;
85 }
86 static int opMOV_BP_imm(uint32_t fetchdat)
87 {
88 BP = getwordf();
89 cycles -= timing_rr;
90 return 0;
91 }
92 static int opMOV_SP_imm(uint32_t fetchdat)
93 {
94 SP = getwordf();
95 cycles -= timing_rr;
96 return 0;
97 }
99 static int opMOV_EAX_imm(uint32_t fetchdat)
100 {
101 uint32_t templ = getlong(); if (abrt) return 0;
102 EAX = templ;
103 cycles -= timing_rr;
104 return 0;
105 }
106 static int opMOV_EBX_imm(uint32_t fetchdat)
107 {
108 uint32_t templ = getlong(); if (abrt) return 0;
109 EBX = templ;
110 cycles -= timing_rr;
111 return 0;
112 }
113 static int opMOV_ECX_imm(uint32_t fetchdat)
114 {
115 uint32_t templ = getlong(); if (abrt) return 0;
116 ECX = templ;
117 cycles -= timing_rr;
118 return 0;
119 }
120 static int opMOV_EDX_imm(uint32_t fetchdat)
121 {
122 uint32_t templ = getlong(); if (abrt) return 0;
123 EDX = templ;
124 cycles -= timing_rr;
125 return 0;
126 }
127 static int opMOV_ESI_imm(uint32_t fetchdat)
128 {
129 uint32_t templ = getlong(); if (abrt) return 0;
130 ESI = templ;
131 cycles -= timing_rr;
132 return 0;
133 }
134 static int opMOV_EDI_imm(uint32_t fetchdat)
135 {
136 uint32_t templ = getlong(); if (abrt) return 0;
137 EDI = templ;
138 cycles -= timing_rr;
139 return 0;
140 }
141 static int opMOV_EBP_imm(uint32_t fetchdat)
142 {
143 uint32_t templ = getlong(); if (abrt) return 0;
144 EBP = templ;
145 cycles -= timing_rr;
146 return 0;
147 }
148 static int opMOV_ESP_imm(uint32_t fetchdat)
149 {
150 uint32_t templ = getlong(); if (abrt) return 0;
151 ESP = templ;
152 cycles -= timing_rr;
153 return 0;
154 }
156 static int opMOV_b_imm_a16(uint32_t fetchdat)
157 {
158 uint8_t temp;
159 fetch_ea_16(fetchdat);
160 temp = readmemb(cs,pc); pc++; if (abrt) return 0;
161 seteab(temp);
162 cycles -= timing_rr;
163 return 0;
164 }
165 static int opMOV_b_imm_a32(uint32_t fetchdat)
166 {
167 uint8_t temp;
168 fetch_ea_32(fetchdat);
169 temp = getbyte(); if (abrt) return 0;
170 seteab(temp);
171 cycles -= timing_rr;
172 return 0;
173 }
175 static int opMOV_w_imm_a16(uint32_t fetchdat)
176 {
177 uint16_t temp;
178 fetch_ea_16(fetchdat);
179 temp = getword(); if (abrt) return 0;
180 seteaw(temp);
181 cycles -= timing_rr;
182 return 0;
183 }
184 static int opMOV_w_imm_a32(uint32_t fetchdat)
185 {
186 uint16_t temp;
187 fetch_ea_32(fetchdat);
188 temp = getword(); if (abrt) return 0;
189 seteaw(temp);
190 cycles -= timing_rr;
191 return 0;
192 }
193 static int opMOV_l_imm_a16(uint32_t fetchdat)
194 {
195 uint32_t temp;
196 fetch_ea_16(fetchdat);
197 temp = getlong(); if (abrt) return 0;
198 seteal(temp);
199 cycles -= timing_rr;
200 return 0;
201 }
202 static int opMOV_l_imm_a32(uint32_t fetchdat)
203 {
204 uint32_t temp;
205 fetch_ea_32(fetchdat);
206 temp = getlong(); if (abrt) return 0;
207 seteal(temp);
208 cycles -= timing_rr;
209 return 0;
210 }
213 static int opMOV_AL_a16(uint32_t fetchdat)
214 {
215 uint16_t addr = getwordf();
216 uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
217 AL = temp;
218 cycles -= (is486) ? 1 : 4;
219 return 0;
220 }
221 static int opMOV_AL_a32(uint32_t fetchdat)
222 {
223 uint32_t addr = getlong();
224 uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
225 AL = temp;
226 cycles -= (is486) ? 1 : 4;
227 return 0;
228 }
229 static int opMOV_AX_a16(uint32_t fetchdat)
230 {
231 uint16_t addr = getwordf();
232 uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0;
233 AX = temp;
234 cycles -= (is486) ? 1 : 4;
235 return 0;
236 }
237 static int opMOV_AX_a32(uint32_t fetchdat)
238 {
239 uint32_t addr = getlong();
240 uint16_t temp = readmemw(ea_seg->base, addr); if (abrt) return 0;
241 AX = temp;
242 cycles -= (is486) ? 1 : 4;
243 return 0;
244 }
245 static int opMOV_EAX_a16(uint32_t fetchdat)
246 {
247 uint16_t addr = getwordf(); if (abrt) return 0;
248 uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0;
249 EAX = temp;
250 cycles -= (is486) ? 1 : 4;
251 return 0;
252 }
253 static int opMOV_EAX_a32(uint32_t fetchdat)
254 {
255 uint32_t addr = getlong(); if (abrt) return 0;
256 uint32_t temp = readmeml(ea_seg->base, addr); if (abrt) return 0;
257 EAX = temp;
258 cycles -= (is486) ? 1 : 4;
259 return 0;
260 }
262 static int opMOV_a16_AL(uint32_t fetchdat)
263 {
264 uint16_t addr = getwordf();
265 writememb(ea_seg->base, addr, AL);
266 cycles -= (is486) ? 1 : 2;
267 return 0;
268 }
269 static int opMOV_a32_AL(uint32_t fetchdat)
270 {
271 uint32_t addr = getlong();
272 writememb(ea_seg->base, addr, AL);
273 cycles -= (is486) ? 1 : 2;
274 return 0;
275 }
276 static int opMOV_a16_AX(uint32_t fetchdat)
277 {
278 uint16_t addr = getwordf();
279 writememw(ea_seg->base, addr, AX);
280 cycles -= (is486) ? 1 : 2;
281 return 0;
282 }
283 static int opMOV_a32_AX(uint32_t fetchdat)
284 {
285 uint32_t addr = getlong();
286 writememw(ea_seg->base, addr, AX);
287 cycles -= (is486) ? 1 : 2;
288 return 0;
289 }
290 static int opMOV_a16_EAX(uint32_t fetchdat)
291 {
292 uint16_t addr = getwordf();
293 writememl(ea_seg->base, addr, EAX);
294 cycles -= (is486) ? 1 : 2;
295 return 0;
296 }
297 static int opMOV_a32_EAX(uint32_t fetchdat)
298 {
299 uint32_t addr = getlong();
300 writememl(ea_seg->base, addr, EAX);
301 cycles -= (is486) ? 1 : 2;
302 return 0;
303 }
306 static int opLEA_w_a16(uint32_t fetchdat)
307 {
308 fetch_ea_16(fetchdat);
309 ILLEGAL_ON(mod == 3);
310 regs[reg].w = eaaddr;
311 cycles -= timing_rr;
312 return 0;
313 }
314 static int opLEA_w_a32(uint32_t fetchdat)
315 {
316 fetch_ea_32(fetchdat);
317 ILLEGAL_ON(mod == 3);
318 regs[reg].w = eaaddr;
319 cycles -= timing_rr;
320 return 0;
321 }
323 static int opLEA_l_a16(uint32_t fetchdat)
324 {
325 fetch_ea_16(fetchdat);
326 ILLEGAL_ON(mod == 3);
327 regs[reg].l = eaaddr & 0xffff;
328 cycles -= timing_rr;
329 return 0;
330 }
331 static int opLEA_l_a32(uint32_t fetchdat)
332 {
333 fetch_ea_32(fetchdat);
334 ILLEGAL_ON(mod == 3);
335 regs[reg].l = eaaddr;
336 cycles -= timing_rr;
337 return 0;
338 }
342 int opXLAT_a16(uint32_t fetchdat)
343 {
344 uint32_t addr = (BX + AL)&0xFFFF;
345 uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
346 AL = temp;
347 cycles -= 5;
348 return 0;
349 }
350 int opXLAT_a32(uint32_t fetchdat)
351 {
352 uint32_t addr = EBX + AL;
353 uint8_t temp = readmemb(ea_seg->base, addr); if (abrt) return 0;
354 AL = temp;
355 cycles -= 5;
356 return 0;
357 }
359 static int opMOV_b_r_a16(uint32_t fetchdat)
360 {
361 if ((uint8_t)fetchdat >= 0xc0)
362 {
363 pc++;
364 setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
365 cycles -= timing_rr;
366 }
367 else
368 {
369 fetch_ea_16(fetchdat);
370 CHECK_WRITE(ea_seg, eaaddr, eaaddr);
371 seteab(getr8(reg));
372 cycles -= is486 ? 1 : 2;
373 }
374 return 0;
375 }
376 static int opMOV_b_r_a32(uint32_t fetchdat)
377 {
378 if ((uint8_t)fetchdat >= 0xc0)
379 {
380 pc++;
381 setr8(fetchdat & 7, getr8((fetchdat >> 3) & 7));
382 cycles -= timing_rr;
383 }
384 else
385 {
386 fetch_ea_32(fetchdat);
387 CHECK_WRITE(ea_seg, eaaddr, eaaddr);
388 seteab(getr8(reg));
389 cycles -= is486 ? 1 : 2;
390 }
391 return 0;
392 }
393 static int opMOV_w_r_a16(uint32_t fetchdat)
394 {
395 if ((uint8_t)fetchdat >= 0xc0)
396 {
397 pc++;
398 regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
399 cycles -= timing_rr;
400 }
401 else
402 {
403 fetch_ea_16(fetchdat);
404 CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
405 seteaw(regs[reg].w);
406 cycles -= is486 ? 1 : 2;
407 }
408 return 0;
409 }
410 static int opMOV_w_r_a32(uint32_t fetchdat)
411 {
412 if ((uint8_t)fetchdat >= 0xc0)
413 {
414 pc++;
415 regs[fetchdat & 7].w = regs[(fetchdat >> 3) & 7].w;
416 cycles -= timing_rr;
417 }
418 else
419 {
420 fetch_ea_32(fetchdat);
421 CHECK_WRITE(ea_seg, eaaddr, eaaddr+1);
422 seteaw(regs[reg].w);
423 cycles -= is486 ? 1 : 2;
424 }
425 return 0;
426 }
427 static int opMOV_l_r_a16(uint32_t fetchdat)
428 {
429 if ((uint8_t)fetchdat >= 0xc0)
430 {
431 pc++;
432 regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
433 cycles -= timing_rr;
434 }
435 else
436 {
437 fetch_ea_16(fetchdat);
438 CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
439 seteal(regs[reg].l);
440 cycles -= is486 ? 1 : 2;
441 }
442 return 0;
443 }
444 static int opMOV_l_r_a32(uint32_t fetchdat)
445 {
446 if ((uint8_t)fetchdat >= 0xc0)
447 {
448 pc++;
449 regs[fetchdat & 7].l = regs[(fetchdat >> 3) & 7].l;
450 cycles -= timing_rr;
451 }
452 else
453 {
454 fetch_ea_32(fetchdat);
455 CHECK_WRITE(ea_seg, eaaddr, eaaddr+3);
456 seteal(regs[reg].l);
457 cycles -= is486 ? 1 : 2;
458 }
459 return 0;
460 }
462 static int opMOV_r_b_a16(uint32_t fetchdat)
463 {
464 if ((uint8_t)fetchdat >= 0xc0)
465 {
466 pc++;
467 setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
468 cycles -= timing_rr;
469 }
470 else
471 {
472 uint8_t temp;
473 fetch_ea_16(fetchdat);
474 CHECK_READ(ea_seg, eaaddr, eaaddr);
475 temp = geteab(); if (abrt) return 0;
476 setr8(reg, temp);
477 cycles -= is486 ? 1 : 4;
478 }
479 return 0;
480 }
481 static int opMOV_r_b_a32(uint32_t fetchdat)
482 {
483 if ((uint8_t)fetchdat >= 0xc0)
484 {
485 pc++;
486 setr8((fetchdat >> 3) & 7, getr8(fetchdat & 7));
487 cycles -= timing_rr;
488 }
489 else
490 {
491 uint8_t temp;
492 fetch_ea_32(fetchdat);
493 CHECK_READ(ea_seg, eaaddr, eaaddr);
494 temp = geteab(); if (abrt) return 0;
495 setr8(reg, temp);
496 cycles -= is486 ? 1 : 4;
497 }
498 return 0;
499 }
500 static int opMOV_r_w_a16(uint32_t fetchdat)
501 {
502 if ((uint8_t)fetchdat >= 0xc0)
503 {
504 pc++;
505 regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
506 cycles -= timing_rr;
507 }
508 else
509 {
510 uint16_t temp;
511 fetch_ea_16(fetchdat);
512 CHECK_READ(ea_seg, eaaddr, eaaddr+1);
513 temp = geteaw(); if (abrt) return 0;
514 regs[reg].w = temp;
515 cycles -= (is486) ? 1 : 4;
516 }
517 return 0;
518 }
519 static int opMOV_r_w_a32(uint32_t fetchdat)
520 {
521 if ((uint8_t)fetchdat >= 0xc0)
522 {
523 pc++;
524 regs[(fetchdat >> 3) & 7].w = regs[fetchdat & 7].w;
525 cycles -= timing_rr;
526 }
527 else
528 {
529 uint16_t temp;
530 fetch_ea_32(fetchdat);
531 CHECK_READ(ea_seg, eaaddr, eaaddr+1);
532 temp = geteaw(); if (abrt) return 0;
533 regs[reg].w = temp;
534 cycles -= (is486) ? 1 : 4;
535 }
536 return 0;
537 }
538 static int opMOV_r_l_a16(uint32_t fetchdat)
539 {
540 if ((uint8_t)fetchdat >= 0xc0)
541 {
542 pc++;
543 regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
544 cycles -= timing_rr;
545 }
546 else
547 {
548 uint32_t temp;
549 fetch_ea_16(fetchdat);
550 CHECK_READ(ea_seg, eaaddr, eaaddr+3);
551 temp = geteal(); if (abrt) return 0;
552 regs[reg].l = temp;
553 cycles -= is486 ? 1 : 4;
554 }
555 return 0;
556 }
557 static int opMOV_r_l_a32(uint32_t fetchdat)
558 {
559 if ((uint8_t)fetchdat >= 0xc0)
560 {
561 pc++;
562 regs[(fetchdat >> 3) & 7].l = regs[fetchdat & 7].l;
563 cycles -= timing_rr;
564 }
565 else
566 {
567 uint32_t temp;
568 fetch_ea_32(fetchdat);
569 CHECK_READ(ea_seg, eaaddr, eaaddr+3);
570 temp = geteal(); if (abrt) return 0;
571 regs[reg].l = temp;
572 cycles -= is486 ? 1 : 4;
573 }
574 return 0;
575 }
