1 #define PUSH_W_OP(reg) \
2 static int opPUSH_ ## reg (uint32_t fetchdat) \
3 { \
4 PUSH_W(reg); \
5 CLOCK_CYCLES((is486) ? 1 : 2); \
6 PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \
7 return cpu_state.abrt; \
8 }
9
10 #define PUSH_L_OP(reg) \
11 static int opPUSH_ ## reg (uint32_t fetchdat) \
12 { \
13 PUSH_L(reg); \
14 CLOCK_CYCLES((is486) ? 1 : 2); \
15 PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \
16 return cpu_state.abrt; \
17 }
18
19 #define POP_W_OP(reg) \
20 static int opPOP_ ## reg (uint32_t fetchdat) \
21 { \
22 reg = POP_W(); \
23 CLOCK_CYCLES((is486) ? 1 : 4); \
24 PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \
25 return cpu_state.abrt; \
26 }
27
28 #define POP_L_OP(reg) \
29 static int opPOP_ ## reg (uint32_t fetchdat) \
30 { \
31 reg = POP_L(); \
32 CLOCK_CYCLES((is486) ? 1 : 4); \
33 PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \
34 return cpu_state.abrt; \
35 }
36
37 PUSH_W_OP(AX)
PUSH_W_OP(BX)38 PUSH_W_OP(BX)
39 PUSH_W_OP(CX)
40 PUSH_W_OP(DX)
41 PUSH_W_OP(SI)
42 PUSH_W_OP(DI)
43 PUSH_W_OP(BP)
44 PUSH_W_OP(SP)
45
46 PUSH_L_OP(EAX)
47 PUSH_L_OP(EBX)
48 PUSH_L_OP(ECX)
49 PUSH_L_OP(EDX)
50 PUSH_L_OP(ESI)
51 PUSH_L_OP(EDI)
52 PUSH_L_OP(EBP)
53 PUSH_L_OP(ESP)
54
55 POP_W_OP(AX)
56 POP_W_OP(BX)
57 POP_W_OP(CX)
58 POP_W_OP(DX)
59 POP_W_OP(SI)
60 POP_W_OP(DI)
61 POP_W_OP(BP)
62 POP_W_OP(SP)
63
64 POP_L_OP(EAX)
65 POP_L_OP(EBX)
66 POP_L_OP(ECX)
67 POP_L_OP(EDX)
68 POP_L_OP(ESI)
69 POP_L_OP(EDI)
70 POP_L_OP(EBP)
71 POP_L_OP(ESP)
72
73
74 static int opPUSHA_w(uint32_t fetchdat)
75 {
76 if (stack32)
77 {
78 writememw(ss, ESP - 2, AX);
79 writememw(ss, ESP - 4, CX);
80 writememw(ss, ESP - 6, DX);
81 writememw(ss, ESP - 8, BX);
82 writememw(ss, ESP - 10, SP);
83 writememw(ss, ESP - 12, BP);
84 writememw(ss, ESP - 14, SI);
85 writememw(ss, ESP - 16, DI);
86 if (!cpu_state.abrt) ESP -= 16;
87 }
88 else
89 {
90 writememw(ss, ((SP - 2) & 0xFFFF), AX);
91 writememw(ss, ((SP - 4) & 0xFFFF), CX);
92 writememw(ss, ((SP - 6) & 0xFFFF), DX);
93 writememw(ss, ((SP - 8) & 0xFFFF), BX);
94 writememw(ss, ((SP - 10) & 0xFFFF), SP);
95 writememw(ss, ((SP - 12) & 0xFFFF), BP);
96 writememw(ss, ((SP - 14) & 0xFFFF), SI);
97 writememw(ss, ((SP - 16) & 0xFFFF), DI);
98 if (!cpu_state.abrt) SP -= 16;
99 }
100 CLOCK_CYCLES((is486) ? 11 : 18);
101 PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0);
102 return cpu_state.abrt;
103 }
opPUSHA_l(uint32_t fetchdat)104 static int opPUSHA_l(uint32_t fetchdat)
105 {
106 if (stack32)
107 {
108 writememl(ss, ESP - 4, EAX);
109 writememl(ss, ESP - 8, ECX);
110 writememl(ss, ESP - 12, EDX);
111 writememl(ss, ESP - 16, EBX);
112 writememl(ss, ESP - 20, ESP);
113 writememl(ss, ESP - 24, EBP);
114 writememl(ss, ESP - 28, ESI);
115 writememl(ss, ESP - 32, EDI);
116 if (!cpu_state.abrt) ESP -= 32;
117 }
118 else
119 {
120 writememl(ss, ((SP - 4) & 0xFFFF), EAX);
121 writememl(ss, ((SP - 8) & 0xFFFF), ECX);
122 writememl(ss, ((SP - 12) & 0xFFFF), EDX);
123 writememl(ss, ((SP - 16) & 0xFFFF), EBX);
124 writememl(ss, ((SP - 20) & 0xFFFF), ESP);
125 writememl(ss, ((SP - 24) & 0xFFFF), EBP);
126 writememl(ss, ((SP - 28) & 0xFFFF), ESI);
127 writememl(ss, ((SP - 32) & 0xFFFF), EDI);
128 if (!cpu_state.abrt) SP -= 32;
129 }
130 CLOCK_CYCLES((is486) ? 11 : 18);
131 PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0);
132 return cpu_state.abrt;
133 }
134
opPOPA_w(uint32_t fetchdat)135 static int opPOPA_w(uint32_t fetchdat)
136 {
137 if (stack32)
138 {
139 DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1;
140 SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1;
141 BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1;
142 BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1;
143 DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1;
144 CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1;
145 AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1;
146 ESP += 16;
147 }
148 else
149 {
150 DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1;
151 SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1;
152 BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1;
153 BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1;
154 DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1;
155 CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1;
156 AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1;
157 SP += 16;
158 }
159 CLOCK_CYCLES((is486) ? 9 : 24);
160 PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0);
161 return 0;
162 }
opPOPA_l(uint32_t fetchdat)163 static int opPOPA_l(uint32_t fetchdat)
164 {
165 if (stack32)
166 {
167 EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1;
168 ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1;
169 EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1;
170 EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1;
171 EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1;
172 ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1;
173 EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1;
174 ESP += 32;
175 }
176 else
177 {
178 EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1;
179 ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1;
180 EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1;
181 EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1;
182 EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1;
183 ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1;
184 EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1;
185 SP += 32;
186 }
187 CLOCK_CYCLES((is486) ? 9 : 24);
188 PREFETCH_RUN(24, 1, -1, 0,7,0,0, 0);
189 return 0;
190 }
191
opPUSH_imm_w(uint32_t fetchdat)192 static int opPUSH_imm_w(uint32_t fetchdat)
193 {
194 uint16_t val = getwordf();
195 PUSH_W(val);
196 CLOCK_CYCLES(2);
197 PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0);
198 return cpu_state.abrt;
199 }
opPUSH_imm_l(uint32_t fetchdat)200 static int opPUSH_imm_l(uint32_t fetchdat)
201 {
202 uint32_t val = getlong(); if (cpu_state.abrt) return 1;
203 PUSH_L(val);
204 CLOCK_CYCLES(2);
205 PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0);
206 return cpu_state.abrt;
207 }
208
opPUSH_imm_bw(uint32_t fetchdat)209 static int opPUSH_imm_bw(uint32_t fetchdat)
210 {
211 uint16_t tempw = getbytef();
212
213 if (tempw & 0x80) tempw |= 0xFF00;
214 PUSH_W(tempw);
215
216 CLOCK_CYCLES(2);
217 PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0);
218 return cpu_state.abrt;
219 }
opPUSH_imm_bl(uint32_t fetchdat)220 static int opPUSH_imm_bl(uint32_t fetchdat)
221 {
222 uint32_t templ = getbytef();
223
224 if (templ & 0x80) templ |= 0xFFFFFF00;
225 PUSH_L(templ);
226
227 CLOCK_CYCLES(2);
228 PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0);
229 return cpu_state.abrt;
230 }
231
opPOPW_a16(uint32_t fetchdat)232 static int opPOPW_a16(uint32_t fetchdat)
233 {
234 uint16_t temp;
235
236 temp = POP_W(); if (cpu_state.abrt) return 1;
237
238 fetch_ea_16(fetchdat);
239 seteaw(temp);
240 if (cpu_state.abrt)
241 {
242 if (stack32) ESP -= 2;
243 else SP -= 2;
244 }
245
246 if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
247 else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
248 PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0);
249 return cpu_state.abrt;
250 }
opPOPW_a32(uint32_t fetchdat)251 static int opPOPW_a32(uint32_t fetchdat)
252 {
253 uint16_t temp;
254
255 temp = POP_W(); if (cpu_state.abrt) return 1;
256
257 fetch_ea_32(fetchdat);
258 seteaw(temp);
259 if (cpu_state.abrt)
260 {
261 if (stack32) ESP -= 2;
262 else SP -= 2;
263 }
264
265 if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
266 else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
267 PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1);
268 return cpu_state.abrt;
269 }
270
opPOPL_a16(uint32_t fetchdat)271 static int opPOPL_a16(uint32_t fetchdat)
272 {
273 uint32_t temp;
274
275 temp = POP_L(); if (cpu_state.abrt) return 1;
276
277 fetch_ea_16(fetchdat);
278 seteal(temp);
279 if (cpu_state.abrt)
280 {
281 if (stack32) ESP -= 4;
282 else SP -= 4;
283 }
284
285 if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
286 else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
287 PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0);
288 return cpu_state.abrt;
289 }
opPOPL_a32(uint32_t fetchdat)290 static int opPOPL_a32(uint32_t fetchdat)
291 {
292 uint32_t temp;
293
294 temp = POP_L(); if (cpu_state.abrt) return 1;
295
296 fetch_ea_32(fetchdat);
297 seteal(temp);
298 if (cpu_state.abrt)
299 {
300 if (stack32) ESP -= 4;
301 else SP -= 4;
302 }
303
304 if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6);
305 else CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5);
306 PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1);
307 return cpu_state.abrt;
308 }
309
310
opENTER_w(uint32_t fetchdat)311 static int opENTER_w(uint32_t fetchdat)
312 {
313 uint16_t offset = getwordf();
314 int count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
315 uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
316 int reads = 0, writes = 1, instr_cycles = 0;
317
318 PUSH_W(BP); if (cpu_state.abrt) return 1;
319 frame_ptr = ESP;
320
321 if (count > 0)
322 {
323 while (--count)
324 {
325 uint16_t tempw;
326
327 BP -= 2;
328 tempw = readmemw(ss, BP);
329 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
330 PUSH_W(tempw);
331 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
332 CLOCK_CYCLES((is486) ? 3 : 4);
333 reads++; writes++; instr_cycles += (is486) ? 3 : 4;
334 }
335 PUSH_W(frame_ptr);
336 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
337 CLOCK_CYCLES((is486) ? 3 : 5);
338 writes++; instr_cycles += (is486) ? 3 : 5;
339 }
340 BP = frame_ptr;
341
342 if (stack32) ESP -= offset;
343 else SP -= offset;
344 CLOCK_CYCLES((is486) ? 14 : 10);
345 instr_cycles += (is486) ? 14 : 10;
346 PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0);
347 return 0;
348 }
opENTER_l(uint32_t fetchdat)349 static int opENTER_l(uint32_t fetchdat)
350 {
351 uint16_t offset = getwordf();
352 int count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
353 uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
354 int reads = 0, writes = 1, instr_cycles = 0;
355
356 PUSH_L(EBP); if (cpu_state.abrt) return 1;
357 frame_ptr = ESP;
358
359 if (count > 0)
360 {
361 while (--count)
362 {
363 uint32_t templ;
364
365 EBP -= 4;
366 templ = readmeml(ss, EBP);
367 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
368 PUSH_L(templ);
369 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
370 CLOCK_CYCLES((is486) ? 3 : 4);
371 reads++; writes++; instr_cycles += (is486) ? 3 : 4;
372 }
373 PUSH_L(frame_ptr);
374 if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
375 CLOCK_CYCLES((is486) ? 3 : 5);
376 writes++; instr_cycles += (is486) ? 3 : 5;
377 }
378 EBP = frame_ptr;
379
380 if (stack32) ESP -= offset;
381 else SP -= offset;
382 CLOCK_CYCLES((is486) ? 14 : 10);
383 instr_cycles += (is486) ? 14 : 10;
384 PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0);
385 return 0;
386 }
387
388
opLEAVE_w(uint32_t fetchdat)389 static int opLEAVE_w(uint32_t fetchdat)
390 {
391 uint32_t tempESP = ESP;
392 uint16_t temp;
393
394 SP = BP;
395 temp = POP_W();
396 if (cpu_state.abrt) { ESP = tempESP; return 1; }
397 BP = temp;
398
399 CLOCK_CYCLES(4);
400 PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0);
401 return 0;
402 }
opLEAVE_l(uint32_t fetchdat)403 static int opLEAVE_l(uint32_t fetchdat)
404 {
405 uint32_t tempESP = ESP;
406 uint32_t temp;
407
408 ESP = EBP;
409 temp = POP_L();
410 if (cpu_state.abrt) { ESP = tempESP; return 1; }
411 EBP = temp;
412
413 CLOCK_CYCLES(4);
414 PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0);
415 return 0;
416 }
417
418
419 #define PUSH_SEG_OPS(seg) \
420 static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \
421 { \
422 PUSH_W(seg); \
423 CLOCK_CYCLES(2); \
424 PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \
425 return cpu_state.abrt; \
426 } \
427 static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \
428 { \
429 PUSH_L(seg); \
430 CLOCK_CYCLES(2); \
431 PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \
432 return cpu_state.abrt; \
433 }
434
435 #define POP_SEG_OPS(seg, realseg) \
436 static int opPOP_ ## seg ## _w(uint32_t fetchdat) \
437 { \
438 uint16_t temp_seg; \
439 uint32_t temp_esp = ESP; \
440 temp_seg = POP_W(); if (cpu_state.abrt) return 1; \
441 loadseg(temp_seg, realseg); if (cpu_state.abrt) ESP = temp_esp; \
442 CLOCK_CYCLES(is486 ? 3 : 7); \
443 PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \
444 return cpu_state.abrt; \
445 } \
446 static int opPOP_ ## seg ## _l(uint32_t fetchdat) \
447 { \
448 uint32_t temp_seg; \
449 uint32_t temp_esp = ESP; \
450 temp_seg = POP_L(); if (cpu_state.abrt) return 1; \
451 loadseg(temp_seg & 0xffff, realseg); if (cpu_state.abrt) ESP = temp_esp; \
452 CLOCK_CYCLES(is486 ? 3 : 7); \
453 PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \
454 return cpu_state.abrt; \
455 }
456
457
458 PUSH_SEG_OPS(CS);
459 PUSH_SEG_OPS(DS);
460 PUSH_SEG_OPS(ES);
461 PUSH_SEG_OPS(FS);
462 PUSH_SEG_OPS(GS);
463 PUSH_SEG_OPS(SS);
464
465 POP_SEG_OPS(DS, &_ds);
466 POP_SEG_OPS(ES, &_es);
467 POP_SEG_OPS(FS, &_fs);
468 POP_SEG_OPS(GS, &_gs);
469
470
opPOP_SS_w(uint32_t fetchdat)471 static int opPOP_SS_w(uint32_t fetchdat)
472 {
473 uint16_t temp_seg;
474 uint32_t temp_esp = ESP;
475 temp_seg = POP_W(); if (cpu_state.abrt) return 1;
476 loadseg(temp_seg, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
477 CLOCK_CYCLES(is486 ? 3 : 7);
478 PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
479
480 cpu_state.oldpc = cpu_state.pc;
481 cpu_state.op32 = use32;
482 cpu_state.ssegs = 0;
483 cpu_state.ea_seg = &_ds;
484 fetchdat = fastreadl(cs + cpu_state.pc);
485 cpu_state.pc++;
486 if (cpu_state.abrt) return 1;
487 x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
488
489 return 1;
490 }
opPOP_SS_l(uint32_t fetchdat)491 static int opPOP_SS_l(uint32_t fetchdat)
492 {
493 uint32_t temp_seg;
494 uint32_t temp_esp = ESP;
495 temp_seg = POP_L(); if (cpu_state.abrt) return 1;
496 loadseg(temp_seg & 0xffff, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
497 CLOCK_CYCLES(is486 ? 3 : 7);
498 PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
499
500 cpu_state.oldpc = cpu_state.pc;
501 cpu_state.op32 = use32;
502 cpu_state.ssegs = 0;
503 cpu_state.ea_seg = &_ds;
504 fetchdat = fastreadl(cs + cpu_state.pc);
505 cpu_state.pc++;
506 if (cpu_state.abrt) return 1;
507 x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
508
509 return 1;
510 }
511