1 #ifndef __I386_H_
2 #define __I386_H_
3
4 #define HAS_I486 0
5 #define HAS_PENTIUM 0
6 #define HAS_MEDIAGX 0
7
8 #define I386OP(XX) i386_##XX
9 #define I486OP(XX) i486_##XX
10 #define PENTIUMOP(XX) pentium_##XX
11 #define MMXOP(XX) mmx_##XX
12
13 #define INPUT_LINE_A20 1
14
15 #ifdef MAME_DEBUG
16 extern int i386_dasm_one(char *buffer, UINT32 pc, UINT8 *oprom, int addr_size, int op_size);
17 #endif
18
19 typedef enum { ES, CS, SS, DS, FS, GS } SREGS;
20
21 #ifdef LSB_FIRST
22 typedef enum {
23 AL = 0,
24 AH = 1,
25 CL = 4,
26 CH = 5,
27 DL = 8,
28 DH = 9,
29 BL = 12,
30 BH = 13
31 } BREGS;
32 #else
33 typedef enum {
34 AL = 3,
35 AH = 2,
36 CL = 7,
37 CH = 6,
38 DL = 11,
39 DH = 10,
40 BL = 15,
41 BH = 14
42 } BREGS;
43 #endif
44
45 #ifdef LSB_FIRST
46 typedef enum {
47 AX = 0,
48 CX = 2,
49 DX = 4,
50 BX = 6,
51 SP = 8,
52 BP = 10,
53 SI = 12,
54 DI = 14
55 } WREGS;
56 #else
57 typedef enum {
58 AX = 1,
59 CX = 3,
60 DX = 5,
61 BX = 7,
62 SP = 9,
63 BP = 11,
64 SI = 13,
65 DI = 15
66 } WREGS;
67 #endif
68
69 typedef enum { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI } DREGS;
70
71 enum
72 {
73 I386_PC = 0,
74 I386_EAX,
75 I386_ECX,
76 I386_EDX,
77 I386_EBX,
78 I386_EBP,
79 I386_ESP,
80 I386_ESI,
81 I386_EDI,
82 I386_CS,
83 I386_SS,
84 I386_DS,
85 I386_ES,
86 I386_FS,
87 I386_GS,
88 I386_EIP,
89 I386_EFLAGS,
90 I386_CR0,
91 I386_CR1,
92 I386_CR2,
93 I386_CR3,
94 I386_DR0,
95 I386_DR1,
96 I386_DR2,
97 I386_DR3,
98 I386_DR4,
99 I386_DR5,
100 I386_DR6,
101 I386_DR7,
102 I386_TR6,
103 I386_TR7,
104 X87_CTRL,
105 X87_STATUS,
106 X87_ST0,
107 X87_ST1,
108 X87_ST2,
109 X87_ST3,
110 X87_ST4,
111 X87_ST5,
112 X87_ST6,
113 X87_ST7
114 };
115
116 typedef struct {
117 UINT16 selector;
118 UINT32 base;
119 UINT32 limit;
120 int d; // Operand size
121 } I386_SREG;
122
123 typedef struct {
124 UINT32 base;
125 UINT16 limit;
126 } I386_SYS_TABLE;
127
128 typedef struct {
129 UINT16 segment;
130 UINT32 base;
131 UINT32 limit;
132 } I386_SEG_DESC;
133
134 typedef union {
135 UINT32 d[8];
136 UINT16 w[16];
137 UINT8 b[32];
138 } I386_GPR;
139
140 typedef union {
141 UINT64 i;
142 double f;
143 } X87_REG;
144
145 typedef struct {
146 I386_GPR reg;
147 I386_SREG sreg[6];
148 UINT32 eip;
149 UINT32 pc;
150 UINT32 prev_eip;
151 UINT32 eflags;
152 UINT8 CF;
153 UINT8 DF;
154 UINT8 SF;
155 UINT8 OF;
156 UINT8 ZF;
157 UINT8 PF;
158 UINT8 AF;
159 UINT8 IF;
160 UINT8 TF;
161
162 UINT8 performed_intersegment_jump;
163
164 UINT32 cr[4]; // Control registers
165 UINT32 dr[8]; // Debug registers
166 UINT32 tr[8]; // Test registers
167
168 I386_SYS_TABLE gdtr; // Global Descriptor Table Register
169 I386_SYS_TABLE idtr; // Interrupt Descriptor Table Register
170 I386_SEG_DESC task; // Task register
171 I386_SEG_DESC ldtr; // Local Descriptor Table Register
172
173 int halted;
174
175 int operand_size;
176 int address_size;
177
178 int segment_prefix;
179 int segment_override;
180
181 int cycles;
182 int base_cycles;
183 UINT8 opcode;
184
185 int irq_line;
186 int irq_hold;
187 UINT32 a20_mask;
188
189 int cpuid_max_input_value_eax;
190 UINT32 cpuid_id0, cpuid_id1, cpuid_id2;
191 UINT32 cpu_version;
192 UINT32 feature_flags;
193 UINT64 tsc;
194
195 // FPU
196 X87_REG fpu_reg[8];
197 UINT16 fpu_control_word;
198 UINT16 fpu_status_word;
199 UINT16 fpu_tag_word;
200 UINT64 fpu_data_ptr;
201 UINT64 fpu_inst_ptr;
202 UINT16 fpu_opcode;
203 int fpu_top;
204
205
206
207 int (*irq_callback)(int);
208
209 void (*opcode_table1_16[256])(void);
210 void (*opcode_table1_32[256])(void);
211 void (*opcode_table2_16[256])(void);
212 void (*opcode_table2_32[256])(void);
213
214 UINT8 *cycle_table_pm;
215 UINT8 *cycle_table_rm;
216 } I386_REGS;
217
218
219 static I386_REGS I;
220
221
222 /* Forward declarations */
223 static void I386OP(decode_opcode)(void);
224 static void I386OP(decode_two_byte)(void);
225
226
227 extern int parity_table[256];
228
229 #define PROTECTED_MODE (I.cr[0] & 0x1)
230 #define STACK_32BIT (I.sreg[SS].d)
231 #define V8086_MODE (I.eflags & 0x00020000)
232
233 #define SetOF_Add32(r,s,d) (I.OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0)
234 #define SetOF_Add16(r,s,d) (I.OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0)
235 #define SetOF_Add8(r,s,d) (I.OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? 1 : 0)
236
237 #define SetOF_Sub32(r,s,d) (I.OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0)
238 #define SetOF_Sub16(r,s,d) (I.OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0)
239 #define SetOF_Sub8(r,s,d) (I.OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0)
240
241 #define SetCF8(x) {I.CF = ((x) & 0x100) ? 1 : 0; }
242 #define SetCF16(x) {I.CF = ((x) & 0x10000) ? 1 : 0; }
243 #define SetCF32(x) {I.CF = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
244
245 #define SetSF(x) (I.SF = (x))
246 #define SetZF(x) (I.ZF = (x))
247 #define SetAF(x,y,z) (I.AF = (((x) ^ ((y) ^ (z))) & 0x10) ? 1 : 0)
248 #define SetPF(x) (I.PF = parity_table[(x) & 0xFF])
249
250 #define SetSZPF8(x) {I.ZF = ((UINT8)(x)==0); I.SF = ((x)&0x80) ? 1 : 0; I.PF = parity_table[x & 0xFF]; }
251 #define SetSZPF16(x) {I.ZF = ((UINT16)(x)==0); I.SF = ((x)&0x8000) ? 1 : 0; I.PF = parity_table[x & 0xFF]; }
252 #define SetSZPF32(x) {I.ZF = ((UINT32)(x)==0); I.SF = ((x)&0x80000000) ? 1 : 0; I.PF = parity_table[x & 0xFF]; }
253
254 /***********************************************************************************/
255
256 typedef struct {
257 struct {
258 int b;
259 int w;
260 int d;
261 } reg;
262 struct {
263 int b;
264 int w;
265 int d;
266 } rm;
267 } MODRM_TABLE;
268
269 extern MODRM_TABLE MODRM_table[256];
270
271 #define REG8(x) (I.reg.b[x])
272 #define REG16(x) (I.reg.w[x])
273 #define REG32(x) (I.reg.d[x])
274
275 #define LOAD_REG8(x) (REG8(MODRM_table[x].reg.b))
276 #define LOAD_REG16(x) (REG16(MODRM_table[x].reg.w))
277 #define LOAD_REG32(x) (REG32(MODRM_table[x].reg.d))
278 #define LOAD_RM8(x) (REG8(MODRM_table[x].rm.b))
279 #define LOAD_RM16(x) (REG16(MODRM_table[x].rm.w))
280 #define LOAD_RM32(x) (REG32(MODRM_table[x].rm.d))
281
282 #define STORE_REG8(x, value) (REG8(MODRM_table[x].reg.b) = value)
283 #define STORE_REG16(x, value) (REG16(MODRM_table[x].reg.w) = value)
284 #define STORE_REG32(x, value) (REG32(MODRM_table[x].reg.d) = value)
285 #define STORE_RM8(x, value) (REG8(MODRM_table[x].rm.b) = value)
286 #define STORE_RM16(x, value) (REG16(MODRM_table[x].rm.w) = value)
287 #define STORE_RM32(x, value) (REG32(MODRM_table[x].rm.d) = value)
288
289 /***********************************************************************************/
290
i386_translate(int segment,UINT32 ip)291 INLINE UINT32 i386_translate(int segment, UINT32 ip)
292 {
293 // TODO: segment limit
294 return I.sreg[segment].base + ip;
295 }
296
translate_address(UINT32 * address)297 INLINE int translate_address(UINT32 *address)
298 {
299 UINT32 a = *address;
300 UINT32 pdbr = I.cr[3] & 0xfffff000;
301 UINT32 directory = (a >> 22) & 0x3ff;
302 UINT32 table = (a >> 12) & 0x3ff;
303 UINT32 offset = a & 0xfff;
304
305 // TODO: 4MB pages
306 UINT32 page_dir = program_read_dword_32le(pdbr + directory * 4);
307 UINT32 page_entry = program_read_dword_32le((page_dir & 0xfffff000) + (table * 4));
308
309 *address = (page_entry & 0xfffff000) | offset;
310 return 1;
311 }
312
CHANGE_PC(UINT32 pc)313 INLINE void CHANGE_PC(UINT32 pc)
314 {
315 UINT32 address;
316 I.pc = i386_translate( CS, pc );
317
318 address = I.pc;
319
320 if (I.cr[0] & 0x80000000) // page translation enabled
321 {
322 translate_address(&address);
323 }
324
325 change_pc(address & I.a20_mask);
326 }
327
NEAR_BRANCH(INT32 offs)328 INLINE void NEAR_BRANCH(INT32 offs)
329 {
330 UINT32 address;
331 /* TODO: limit */
332 I.eip += offs;
333 I.pc += offs;
334
335 address = I.pc;
336
337 if (I.cr[0] & 0x80000000) // page translation enabled
338 {
339 translate_address(&address);
340 }
341
342 change_pc(address & I.a20_mask);
343 }
344
FETCH(void)345 INLINE UINT8 FETCH(void)
346 {
347 UINT8 value;
348 UINT32 address = I.pc;
349
350 if (I.cr[0] & 0x80000000) // page translation enabled
351 {
352 translate_address(&address);
353 }
354
355 value = cpu_readop(address & I.a20_mask);
356 I.eip++;
357 I.pc++;
358 return value;
359 }
FETCH16(void)360 INLINE UINT16 FETCH16(void)
361 {
362 UINT16 value;
363 UINT32 address = I.pc;
364
365 if (I.cr[0] & 0x80000000) // page translation enabled
366 {
367 translate_address(&address);
368 }
369
370 if( address & 0x1 ) { /* Unaligned read */
371 address &= I.a20_mask;
372 value = (cpu_readop(address+0) << 0) |
373 (cpu_readop(address+1) << 8);
374 } else {
375 address &= I.a20_mask;
376 value = cpu_readop16(address);
377 }
378 I.eip += 2;
379 I.pc += 2;
380 return value;
381 }
FETCH32(void)382 INLINE UINT32 FETCH32(void)
383 {
384 UINT32 value;
385 UINT32 address = I.pc;
386
387 if (I.cr[0] & 0x80000000) // page translation enabled
388 {
389 translate_address(&address);
390 }
391
392 if( I.pc & 0x3 ) { /* Unaligned read */
393 address &= I.a20_mask;
394 value = (cpu_readop(address+0) << 0) |
395 (cpu_readop(address+1) << 8) |
396 (cpu_readop(address+2) << 16) |
397 (cpu_readop(address+3) << 24);
398 } else {
399 address &= I.a20_mask;
400 value = cpu_readop32(address);
401 }
402 I.eip += 4;
403 I.pc += 4;
404 return value;
405 }
406
READ8(UINT32 ea)407 INLINE UINT8 READ8(UINT32 ea)
408 {
409 UINT32 address = ea;
410
411 if (I.cr[0] & 0x80000000) // page translation enabled
412 {
413 translate_address(&address);
414 }
415
416 address &= I.a20_mask;
417 return program_read_byte_32le(address);
418 }
READ16(UINT32 ea)419 INLINE UINT16 READ16(UINT32 ea)
420 {
421 UINT16 value;
422 UINT32 address = ea;
423
424 if (I.cr[0] & 0x80000000) // page translation enabled
425 {
426 translate_address(&address);
427 }
428
429 address &= I.a20_mask;
430 if( ea & 0x1 ) { /* Unaligned read */
431 value = (program_read_byte_32le( address+0 ) << 0) |
432 (program_read_byte_32le( address+1 ) << 8);
433 } else {
434 value = program_read_word_32le( address );
435 }
436 return value;
437 }
READ32(UINT32 ea)438 INLINE UINT32 READ32(UINT32 ea)
439 {
440 UINT32 value;
441 UINT32 address = ea;
442
443 if (I.cr[0] & 0x80000000) // page translation enabled
444 {
445 translate_address(&address);
446 }
447
448 address &= I.a20_mask;
449 if( ea & 0x3 ) { /* Unaligned read */
450 value = (program_read_byte_32le( address+0 ) << 0) |
451 (program_read_byte_32le( address+1 ) << 8) |
452 (program_read_byte_32le( address+2 ) << 16) |
453 (program_read_byte_32le( address+3 ) << 24);
454 } else {
455 value = program_read_dword_32le( address );
456 }
457 return value;
458 }
459
WRITE8(UINT32 ea,UINT8 value)460 INLINE void WRITE8(UINT32 ea, UINT8 value)
461 {
462 UINT32 address = ea;
463
464 if (I.cr[0] & 0x80000000) // page translation enabled
465 {
466 translate_address(&address);
467 }
468
469 address &= I.a20_mask;
470 program_write_byte_32le(address, value);
471 }
WRITE16(UINT32 ea,UINT16 value)472 INLINE void WRITE16(UINT32 ea, UINT16 value)
473 {
474 UINT32 address = ea;
475
476 if (I.cr[0] & 0x80000000) // page translation enabled
477 {
478 translate_address(&address);
479 }
480
481 address &= I.a20_mask;
482 if( ea & 0x1 ) { /* Unaligned write */
483 program_write_byte_32le( address+0, value & 0xff );
484 program_write_byte_32le( address+1, (value >> 8) & 0xff );
485 } else {
486 program_write_word_32le(address, value);
487 }
488 }
WRITE32(UINT32 ea,UINT32 value)489 INLINE void WRITE32(UINT32 ea, UINT32 value)
490 {
491 UINT32 address = ea;
492
493 if (I.cr[0] & 0x80000000) // page translation enabled
494 {
495 translate_address(&address);
496 }
497
498 ea &= I.a20_mask;
499 if( ea & 0x3 ) { /* Unaligned write */
500 program_write_byte_32le( address+0, value & 0xff );
501 program_write_byte_32le( address+1, (value >> 8) & 0xff );
502 program_write_byte_32le( address+2, (value >> 16) & 0xff );
503 program_write_byte_32le( address+3, (value >> 24) & 0xff );
504 } else {
505 program_write_dword_32le(address, value);
506 }
507 }
508
509 /***********************************************************************************/
510
OR8(UINT8 dst,UINT8 src)511 INLINE UINT8 OR8(UINT8 dst, UINT8 src)
512 {
513 UINT8 res = dst | src;
514 I.CF = I.OF = 0;
515 SetSZPF8(res);
516 return res;
517 }
OR16(UINT16 dst,UINT16 src)518 INLINE UINT16 OR16(UINT16 dst, UINT16 src)
519 {
520 UINT16 res = dst | src;
521 I.CF = I.OF = 0;
522 SetSZPF16(res);
523 return res;
524 }
OR32(UINT32 dst,UINT32 src)525 INLINE UINT32 OR32(UINT32 dst, UINT32 src)
526 {
527 UINT32 res = dst | src;
528 I.CF = I.OF = 0;
529 SetSZPF32(res);
530 return res;
531 }
532
AND8(UINT8 dst,UINT8 src)533 INLINE UINT8 AND8(UINT8 dst, UINT8 src)
534 {
535 UINT8 res = dst & src;
536 I.CF = I.OF = 0;
537 SetSZPF8(res);
538 return res;
539 }
AND16(UINT16 dst,UINT16 src)540 INLINE UINT16 AND16(UINT16 dst, UINT16 src)
541 {
542 UINT16 res = dst & src;
543 I.CF = I.OF = 0;
544 SetSZPF16(res);
545 return res;
546 }
AND32(UINT32 dst,UINT32 src)547 INLINE UINT32 AND32(UINT32 dst, UINT32 src)
548 {
549 UINT32 res = dst & src;
550 I.CF = I.OF = 0;
551 SetSZPF32(res);
552 return res;
553 }
554
XOR8(UINT8 dst,UINT8 src)555 INLINE UINT8 XOR8(UINT8 dst, UINT8 src)
556 {
557 UINT8 res = dst ^ src;
558 I.CF = I.OF = 0;
559 SetSZPF8(res);
560 return res;
561 }
XOR16(UINT16 dst,UINT16 src)562 INLINE UINT16 XOR16(UINT16 dst, UINT16 src)
563 {
564 UINT16 res = dst ^ src;
565 I.CF = I.OF = 0;
566 SetSZPF16(res);
567 return res;
568 }
XOR32(UINT32 dst,UINT32 src)569 INLINE UINT32 XOR32(UINT32 dst, UINT32 src)
570 {
571 UINT32 res = dst ^ src;
572 I.CF = I.OF = 0;
573 SetSZPF32(res);
574 return res;
575 }
576
SUB8(UINT8 dst,UINT8 src)577 INLINE UINT8 SUB8(UINT8 dst, UINT8 src)
578 {
579 UINT16 res = (UINT16)dst - (UINT16)src;
580 SetCF8(res);
581 SetOF_Sub8(res,src,dst);
582 SetAF(res,src,dst);
583 SetSZPF8(res);
584 return (UINT8)res;
585 }
SUB16(UINT16 dst,UINT16 src)586 INLINE UINT16 SUB16(UINT16 dst, UINT16 src)
587 {
588 UINT32 res = (UINT32)dst - (UINT32)src;
589 SetCF16(res);
590 SetOF_Sub16(res,src,dst);
591 SetAF(res,src,dst);
592 SetSZPF16(res);
593 return (UINT16)res;
594 }
SUB32(UINT32 dst,UINT32 src)595 INLINE UINT32 SUB32(UINT32 dst, UINT32 src)
596 {
597 UINT64 res = (UINT64)dst - (UINT64)src;
598 SetCF32(res);
599 SetOF_Sub32(res,src,dst);
600 SetAF(res,src,dst);
601 SetSZPF32(res);
602 return (UINT32)res;
603 }
604
ADD8(UINT8 dst,UINT8 src)605 INLINE UINT8 ADD8(UINT8 dst, UINT8 src)
606 {
607 UINT16 res = (UINT16)dst + (UINT16)src;
608 SetCF8(res);
609 SetOF_Add8(res,src,dst);
610 SetAF(res,src,dst);
611 SetSZPF8(res);
612 return (UINT8)res;
613 }
ADD16(UINT16 dst,UINT16 src)614 INLINE UINT16 ADD16(UINT16 dst, UINT16 src)
615 {
616 UINT32 res = (UINT32)dst + (UINT32)src;
617 SetCF16(res);
618 SetOF_Add16(res,src,dst);
619 SetAF(res,src,dst);
620 SetSZPF16(res);
621 return (UINT16)res;
622 }
ADD32(UINT32 dst,UINT32 src)623 INLINE UINT32 ADD32(UINT32 dst, UINT32 src)
624 {
625 UINT64 res = (UINT64)dst + (UINT64)src;
626 SetCF32(res);
627 SetOF_Add32(res,src,dst);
628 SetAF(res,src,dst);
629 SetSZPF32(res);
630 return (UINT32)res;
631 }
632
INC8(UINT8 dst)633 INLINE UINT8 INC8(UINT8 dst)
634 {
635 UINT16 res = (UINT16)dst + 1;
636 SetOF_Add8(res,1,dst);
637 SetAF(res,1,dst);
638 SetSZPF8(res);
639 return (UINT8)res;
640 }
INC16(UINT16 dst)641 INLINE UINT16 INC16(UINT16 dst)
642 {
643 UINT32 res = (UINT32)dst + 1;
644 SetOF_Add16(res,1,dst);
645 SetAF(res,1,dst);
646 SetSZPF16(res);
647 return (UINT16)res;
648 }
INC32(UINT32 dst)649 INLINE UINT32 INC32(UINT32 dst)
650 {
651 UINT64 res = (UINT64)dst + 1;
652 SetOF_Add32(res,1,dst);
653 SetAF(res,1,dst);
654 SetSZPF32(res);
655 return (UINT32)res;
656 }
657
DEC8(UINT8 dst)658 INLINE UINT8 DEC8(UINT8 dst)
659 {
660 UINT16 res = (UINT16)dst - 1;
661 SetOF_Sub8(res,1,dst);
662 SetAF(res,1,dst);
663 SetSZPF8(res);
664 return (UINT8)res;
665 }
DEC16(UINT16 dst)666 INLINE UINT16 DEC16(UINT16 dst)
667 {
668 UINT32 res = (UINT32)dst - 1;
669 SetOF_Sub16(res,1,dst);
670 SetAF(res,1,dst);
671 SetSZPF16(res);
672 return (UINT16)res;
673 }
DEC32(UINT32 dst)674 INLINE UINT32 DEC32(UINT32 dst)
675 {
676 UINT64 res = (UINT64)dst - 1;
677 SetOF_Sub32(res,1,dst);
678 SetAF(res,1,dst);
679 SetSZPF32(res);
680 return (UINT32)res;
681 }
682
683
684
PUSH16(UINT16 value)685 INLINE void PUSH16(UINT16 value)
686 {
687 UINT32 ea;
688 if( STACK_32BIT ) {
689 REG32(ESP) -= 2;
690 ea = i386_translate( SS, REG32(ESP) );
691 WRITE16( ea, value );
692 } else {
693 REG16(SP) -= 2;
694 ea = i386_translate( SS, REG16(SP) );
695 WRITE16( ea, value );
696 }
697 }
PUSH32(UINT32 value)698 INLINE void PUSH32(UINT32 value)
699 {
700 UINT32 ea;
701 if( STACK_32BIT ) {
702 REG32(ESP) -= 4;
703 ea = i386_translate( SS, REG32(ESP) );
704 WRITE32( ea, value );
705 } else {
706 REG16(SP) -= 4;
707 ea = i386_translate( SS, REG16(SP) );
708 WRITE32( ea, value );
709 }
710 }
PUSH8(UINT8 value)711 INLINE void PUSH8(UINT8 value)
712 {
713 if( I.operand_size ) {
714 PUSH32((INT32)(INT8)value);
715 } else {
716 PUSH16((INT16)(INT8)value);
717 }
718 }
719
POP8(void)720 INLINE UINT8 POP8(void)
721 {
722 UINT8 value;
723 UINT32 ea;
724 if( STACK_32BIT ) {
725 ea = i386_translate( SS, REG32(ESP) );
726 value = READ8( ea );
727 REG32(ESP) += 1;
728 } else {
729 ea = i386_translate( SS, REG16(SP) );
730 value = READ8( ea );
731 REG16(SP) += 1;
732 }
733 return value;
734 }
POP16(void)735 INLINE UINT16 POP16(void)
736 {
737 UINT16 value;
738 UINT32 ea;
739 if( STACK_32BIT ) {
740 ea = i386_translate( SS, REG32(ESP) );
741 value = READ16( ea );
742 REG32(ESP) += 2;
743 } else {
744 ea = i386_translate( SS, REG16(SP) );
745 value = READ16( ea );
746 REG16(SP) += 2;
747 }
748 return value;
749 }
POP32(void)750 INLINE UINT32 POP32(void)
751 {
752 UINT32 value;
753 UINT32 ea;
754 if( STACK_32BIT ) {
755 ea = i386_translate( SS, REG32(ESP) );
756 value = READ32( ea );
757 REG32(ESP) += 4;
758 } else {
759 ea = i386_translate( SS, REG16(SP) );
760 value = READ32( ea );
761 REG16(SP) += 4;
762 }
763 return value;
764 }
765
BUMP_SI(int adjustment)766 INLINE void BUMP_SI(int adjustment)
767 {
768 if ( I.address_size )
769 REG32(ESI) += ((I.DF) ? -adjustment : +adjustment);
770 else
771 REG16(SI) += ((I.DF) ? -adjustment : +adjustment);
772 }
773
BUMP_DI(int adjustment)774 INLINE void BUMP_DI(int adjustment)
775 {
776 if ( I.address_size )
777 REG32(EDI) += ((I.DF) ? -adjustment : +adjustment);
778 else
779 REG16(DI) += ((I.DF) ? -adjustment : +adjustment);
780 }
781
782
783
784 /***********************************************************************************/
785
786 #define READPORT8(port) (io_read_byte_32le(port))
787 #define READPORT16(port) (io_read_word_32le(port))
788 #define READPORT32(port) (io_read_dword_32le(port))
789 #define WRITEPORT8(port, value) (io_write_byte_32le(port, value))
790 #define WRITEPORT16(port, value) (io_write_word_32le(port, value))
791 #define WRITEPORT32(port, value) (io_write_dword_32le(port, value))
792
793 #endif
794