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