I386OP(shift_rotate16)1 static UINT16 I386OP(shift_rotate16)(UINT8 modrm, UINT32 value, UINT8 shift)
2 {
3 	UINT16 src = value;
4 	UINT16 dst = value;
5 
6 	if( shift == 0 ) {
7 		CYCLES_RM(modrm, 3, 7);
8 	} else if( shift == 1 ) {
9 
10 		switch( (modrm >> 3) & 0x7 )
11 		{
12 			case 0:			/* ROL rm16, 1 */
13 				I.CF = (src & 0x8000) ? 1 : 0;
14 				dst = (src << 1) + I.CF;
15 				I.OF = ((src ^ dst) & 0x8000) ? 1 : 0;
16 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
17 				break;
18 			case 1:			/* ROR rm16, 1 */
19 				I.CF = (src & 0x1) ? 1 : 0;
20 				dst = (I.CF << 15) | (src >> 1);
21 				I.OF = ((src ^ dst) & 0x8000) ? 1 : 0;
22 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
23 				break;
24 			case 2:			/* RCL rm16, 1 */
25 				dst = (src << 1) + I.CF;
26 				I.CF = (src & 0x8000) ? 1 : 0;
27 				I.OF = ((src ^ dst) & 0x8000) ? 1 : 0;
28 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
29 				break;
30 			case 3:			/* RCR rm16, 1 */
31 				dst = (I.CF << 15) | (src >> 1);
32 				I.CF = src & 0x1;
33 				I.OF = ((src ^ dst) & 0x8000) ? 1 : 0;
34 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
35 				break;
36 			case 4:			/* SHL/SAL rm16, 1 */
37 			case 6:
38 				dst = src << 1;
39 				I.CF = (src & 0x8000) ? 1 : 0;
40 				I.OF = (((I.CF << 15) ^ dst) & 0x8000) ? 1 : 0;
41 				SetSZPF16(dst);
42 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
43 				break;
44 			case 5:			/* SHR rm16, 1 */
45 				dst = src >> 1;
46 				I.CF = src & 0x1;
47 				I.OF = (dst & 0x8000) ? 1 : 0;
48 				SetSZPF16(dst);
49 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
50 				break;
51 			case 7:			/* SAR rm16, 1 */
52 				dst = (INT16)(src) >> 1;
53 				I.CF = src & 0x1;
54 				I.OF = 0;
55 				SetSZPF16(dst);
56 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
57 				break;
58 		}
59 	} else {
60 
61 		switch( (modrm >> 3) & 0x7 )
62 		{
63 			case 0:			/* ROL rm16, i8 */
64 				dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
65 					  ((src & ((UINT16)0xffff << (16-shift))) >> (16-shift));
66 				I.CF = (src >> (16-shift)) & 0x1;
67 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
68 				break;
69 			case 1:			/* ROR rm16, i8 */
70 				dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
71 					  ((src & ((UINT16)0xffff >> (16-shift))) << (16-shift));
72 				I.CF = (src >> (shift-1)) & 0x1;
73 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
74 				break;
75 			case 2:			/* RCL rm16, i8 */
76 				dst = ((src & ((UINT16)0xffff >> shift)) << shift) |
77 					  ((src & ((UINT16)0xffff << (17-shift))) >> (17-shift)) |
78 					  (I.CF << (shift-1));
79 				I.CF = (src >> (16-shift)) & 0x1;
80 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
81 				break;
82 			case 3:			/* RCR rm16, i8 */
83 				dst = ((src & ((UINT16)0xffff << shift)) >> shift) |
84 					  ((src & ((UINT16)0xffff >> (16-shift))) << (17-shift)) |
85 					  (I.CF << (16-shift));
86 				I.CF = (src >> (shift-1)) & 0x1;
87 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
88 				break;
89 			case 4:			/* SHL/SAL rm16, i8 */
90 			case 6:
91 				dst = src << shift;
92 				I.CF = (src & (1 << (16-shift))) ? 1 : 0;
93 				SetSZPF16(dst);
94 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
95 				break;
96 			case 5:			/* SHR rm16, i8 */
97 				dst = src >> shift;
98 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
99 				SetSZPF16(dst);
100 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
101 				break;
102 			case 7:			/* SAR rm16, i8 */
103 				dst = (INT16)src >> shift;
104 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
105 				SetSZPF16(dst);
106 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
107 				break;
108 		}
109 
110 	}
111 	return dst;
112 }
113 
114 
115 
I386OP(adc_rm16_r16)116 static void I386OP(adc_rm16_r16)(void)		// Opcode 0x11
117 {
118 	UINT16 src, dst;
119 	UINT8 modrm = FETCH();
120 	if( modrm >= 0xc0 ) {
121 		src = LOAD_REG16(modrm);
122 		dst = LOAD_RM16(modrm);
123 		src = ADD16(src, I.CF);
124 		dst = ADD16(dst, src);
125 		STORE_RM16(modrm, dst);
126 		CYCLES(CYCLES_ALU_REG_REG);
127 	} else {
128 		UINT32 ea = GetEA(modrm);
129 		src = LOAD_REG16(modrm);
130 		dst = READ16(ea);
131 		src = ADD16(src, I.CF);
132 		dst = ADD16(dst, src);
133 		WRITE16(ea, dst);
134 		CYCLES(CYCLES_ALU_REG_MEM);
135 	}
136 }
137 
I386OP(adc_r16_rm16)138 static void I386OP(adc_r16_rm16)(void)		// Opcode 0x13
139 {
140 	UINT16 src, dst;
141 	UINT8 modrm = FETCH();
142 	if( modrm >= 0xc0 ) {
143 		src = LOAD_RM16(modrm);
144 		dst = LOAD_REG16(modrm);
145 		src = ADD16(src, I.CF);
146 		dst = ADD16(dst, src);
147 		STORE_REG16(modrm, dst);
148 		CYCLES(CYCLES_ALU_REG_REG);
149 	} else {
150 		UINT32 ea = GetEA(modrm);
151 		src = READ16(ea);
152 		dst = LOAD_REG16(modrm);
153 		src = ADD16(src, I.CF);
154 		dst = ADD16(dst, src);
155 		STORE_REG16(modrm, dst);
156 		CYCLES(CYCLES_ALU_MEM_REG);
157 	}
158 }
159 
I386OP(adc_ax_i16)160 static void I386OP(adc_ax_i16)(void)		// Opcode 0x15
161 {
162 	UINT16 src, dst;
163 	src = FETCH16();
164 	dst = REG16(AX);
165 	src = ADD16(src, I.CF);
166 	dst = ADD16(dst, src);
167 	REG16(AX) = dst;
168 	CYCLES(CYCLES_ALU_IMM_ACC);
169 }
170 
I386OP(add_rm16_r16)171 static void I386OP(add_rm16_r16)(void)		// Opcode 0x01
172 {
173 	UINT16 src, dst;
174 	UINT8 modrm = FETCH();
175 	if( modrm >= 0xc0 ) {
176 		src = LOAD_REG16(modrm);
177 		dst = LOAD_RM16(modrm);
178 		dst = ADD16(dst, src);
179 		STORE_RM16(modrm, dst);
180 		CYCLES(CYCLES_ALU_REG_REG);
181 	} else {
182 		UINT32 ea = GetEA(modrm);
183 		src = LOAD_REG16(modrm);
184 		dst = READ16(ea);
185 		dst = ADD16(dst, src);
186 		WRITE16(ea, dst);
187 		CYCLES(CYCLES_ALU_REG_MEM);
188 	}
189 }
190 
I386OP(add_r16_rm16)191 static void I386OP(add_r16_rm16)(void)		// Opcode 0x03
192 {
193 	UINT16 src, dst;
194 	UINT8 modrm = FETCH();
195 	if( modrm >= 0xc0 ) {
196 		src = LOAD_RM16(modrm);
197 		dst = LOAD_REG16(modrm);
198 		dst = ADD16(dst, src);
199 		STORE_REG16(modrm, dst);
200 		CYCLES(CYCLES_ALU_REG_REG);
201 	} else {
202 		UINT32 ea = GetEA(modrm);
203 		src = READ16(ea);
204 		dst = LOAD_REG16(modrm);
205 		dst = ADD16(dst, src);
206 		STORE_REG16(modrm, dst);
207 		CYCLES(CYCLES_ALU_MEM_REG);
208 	}
209 }
210 
I386OP(add_ax_i16)211 static void I386OP(add_ax_i16)(void)		// Opcode 0x05
212 {
213 	UINT16 src, dst;
214 	src = FETCH16();
215 	dst = REG16(AX);
216 	dst = ADD16(dst, src);
217 	REG16(AX) = dst;
218 	CYCLES(CYCLES_ALU_IMM_ACC);
219 }
220 
I386OP(and_rm16_r16)221 static void I386OP(and_rm16_r16)(void)		// Opcode 0x21
222 {
223 	UINT16 src, dst;
224 	UINT8 modrm = FETCH();
225 	if( modrm >= 0xc0 ) {
226 		src = LOAD_REG16(modrm);
227 		dst = LOAD_RM16(modrm);
228 		dst = AND16(dst, src);
229 		STORE_RM16(modrm, dst);
230 		CYCLES(CYCLES_ALU_REG_REG);
231 	} else {
232 		UINT32 ea = GetEA(modrm);
233 		src = LOAD_REG16(modrm);
234 		dst = READ16(ea);
235 		dst = AND16(dst, src);
236 		WRITE16(ea, dst);
237 		CYCLES(CYCLES_ALU_REG_MEM);
238 	}
239 }
240 
I386OP(and_r16_rm16)241 static void I386OP(and_r16_rm16)(void)		// Opcode 0x23
242 {
243 	UINT16 src, dst;
244 	UINT8 modrm = FETCH();
245 	if( modrm >= 0xc0 ) {
246 		src = LOAD_RM16(modrm);
247 		dst = LOAD_REG16(modrm);
248 		dst = AND16(dst, src);
249 		STORE_REG16(modrm, dst);
250 		CYCLES(CYCLES_ALU_REG_REG);
251 	} else {
252 		UINT32 ea = GetEA(modrm);
253 		src = READ16(ea);
254 		dst = LOAD_REG16(modrm);
255 		dst = AND16(dst, src);
256 		STORE_REG16(modrm, dst);
257 		CYCLES(CYCLES_ALU_MEM_REG);
258 	}
259 }
260 
I386OP(and_ax_i16)261 static void I386OP(and_ax_i16)(void)		// Opcode 0x25
262 {
263 	UINT16 src, dst;
264 	src = FETCH16();
265 	dst = REG16(AX);
266 	dst = AND16(dst, src);
267 	REG16(AX) = dst;
268 	CYCLES(CYCLES_ALU_IMM_ACC);
269 }
270 
I386OP(bsf_r16_rm16)271 static void I386OP(bsf_r16_rm16)(void)		// Opcode 0x0f bc
272 {
273 	UINT16 src, dst, temp;
274 	UINT8 modrm = FETCH();
275 
276 	if( modrm >= 0xc0 ) {
277 		src = LOAD_RM16(modrm);
278 	} else {
279 		UINT32 ea = GetEA(modrm);
280 		src = READ16(ea);
281 	}
282 
283 	dst = 0;
284 
285 	if( src == 0 ) {
286 		I.ZF = 1;
287 	} else {
288 		I.ZF = 0;
289 		temp = 0;
290 		while( (src & (1 << temp)) == 0 ) {
291 			temp++;
292 			dst = temp;
293 			CYCLES(CYCLES_BSF);
294 		}
295 	}
296 	CYCLES(CYCLES_BSF_BASE);
297 	STORE_REG16(modrm, dst);
298 }
299 
I386OP(bsr_r16_rm16)300 static void I386OP(bsr_r16_rm16)(void)		// Opcode 0x0f bd
301 {
302 	UINT16 src, dst, temp;
303 	UINT8 modrm = FETCH();
304 
305 	if( modrm >= 0xc0 ) {
306 		src = LOAD_RM16(modrm);
307 	} else {
308 		UINT32 ea = GetEA(modrm);
309 		src = READ16(ea);
310 	}
311 
312 	dst = 0;
313 
314 	if( src == 0 ) {
315 		I.ZF = 1;
316 	} else {
317 		I.ZF = 0;
318 		temp = 15;
319 		while( (src & (1 << temp)) == 0 ) {
320 			temp--;
321 			dst = temp;
322 			CYCLES(CYCLES_BSR);
323 		}
324 	}
325 	CYCLES(CYCLES_BSR_BASE);
326 	STORE_REG16(modrm, dst);
327 }
328 
329 
I386OP(bt_rm16_r16)330 static void I386OP(bt_rm16_r16)(void)		// Opcode 0x0f a3
331 {
332 	UINT8 modrm = FETCH();
333 	if( modrm >= 0xc0 ) {
334 		UINT16 dst = LOAD_RM16(modrm);
335 		UINT16 bit = LOAD_REG16(modrm);
336 
337 		if( dst & (1 << bit) )
338 			I.CF = 1;
339 		else
340 			I.CF = 0;
341 
342 		CYCLES(CYCLES_BT_REG_REG);
343 	} else {
344 		UINT32 ea = GetEA(modrm);
345 		UINT16 dst = READ16(ea);
346 		UINT16 bit = LOAD_REG16(modrm);
347 
348 		if( dst & (1 << bit) )
349 			I.CF = 1;
350 		else
351 			I.CF = 0;
352 
353 		CYCLES(CYCLES_BT_REG_MEM);
354 	}
355 }
356 
I386OP(btc_rm16_r16)357 static void I386OP(btc_rm16_r16)(void)		// Opcode 0x0f bb
358 {
359 	UINT8 modrm = FETCH();
360 	if( modrm >= 0xc0 ) {
361 		UINT16 dst = LOAD_RM16(modrm);
362 		UINT16 bit = LOAD_REG16(modrm);
363 
364 		if( dst & (1 << bit) )
365 			I.CF = 1;
366 		else
367 			I.CF = 0;
368 		dst ^= (1 << bit);
369 
370 		STORE_RM16(modrm, dst);
371 		CYCLES(CYCLES_BTC_REG_REG);
372 	} else {
373 		UINT32 ea = GetEA(modrm);
374 		UINT16 dst = READ16(ea);
375 		UINT16 bit = LOAD_REG16(modrm);
376 
377 		if( dst & (1 << bit) )
378 			I.CF = 1;
379 		else
380 			I.CF = 0;
381 		dst ^= (1 << bit);
382 
383 		WRITE16(ea, dst);
384 		CYCLES(CYCLES_BTC_REG_MEM);
385 	}
386 }
387 
I386OP(btr_rm16_r16)388 static void I386OP(btr_rm16_r16)(void)		// Opcode 0x0f b3
389 {
390 	UINT8 modrm = FETCH();
391 	if( modrm >= 0xc0 ) {
392 		UINT16 dst = LOAD_RM16(modrm);
393 		UINT16 bit = LOAD_REG16(modrm);
394 
395 		if( dst & (1 << bit) )
396 			I.CF = 1;
397 		else
398 			I.CF = 0;
399 		dst &= ~(1 << bit);
400 
401 		STORE_RM16(modrm, dst);
402 		CYCLES(CYCLES_BTR_REG_REG);
403 	} else {
404 		UINT32 ea = GetEA(modrm);
405 		UINT16 dst = READ16(ea);
406 		UINT16 bit = LOAD_REG16(modrm);
407 
408 		if( dst & (1 << bit) )
409 			I.CF = 1;
410 		else
411 			I.CF = 0;
412 		dst &= ~(1 << bit);
413 
414 		WRITE16(ea, dst);
415 		CYCLES(CYCLES_BTR_REG_MEM);
416 	}
417 }
418 
I386OP(bts_rm16_r16)419 static void I386OP(bts_rm16_r16)(void)		// Opcode 0x0f ab
420 {
421 	UINT8 modrm = FETCH();
422 	if( modrm >= 0xc0 ) {
423 		UINT16 dst = LOAD_RM16(modrm);
424 		UINT16 bit = LOAD_REG16(modrm);
425 
426 		if( dst & (1 << bit) )
427 			I.CF = 1;
428 		else
429 			I.CF = 0;
430 		dst |= (1 << bit);
431 
432 		STORE_RM16(modrm, dst);
433 		CYCLES(CYCLES_BTS_REG_REG);
434 	} else {
435 		UINT32 ea = GetEA(modrm);
436 		UINT16 dst = READ16(ea);
437 		UINT16 bit = LOAD_REG16(modrm);
438 
439 		if( dst & (1 << bit) )
440 			I.CF = 1;
441 		else
442 			I.CF = 0;
443 		dst |= (1 << bit);
444 
445 		WRITE16(ea, dst);
446 		CYCLES(CYCLES_BTS_REG_MEM);
447 	}
448 }
449 
I386OP(call_abs16)450 static void I386OP(call_abs16)(void)		// Opcode 0x9a
451 {
452 	UINT16 offset = FETCH16();
453 	UINT16 ptr = FETCH16();
454 
455 	if( PROTECTED_MODE ) {
456 		/* TODO */
457 	//	osd_die("i386: call_abs16 in protected mode unimplemented\n");
458 	} else {
459 		if (I.sreg[CS].d)
460 		{
461 			PUSH32( I.sreg[CS].selector );
462 			PUSH32( I.eip );
463 		}
464 		else
465 		{
466 			PUSH16( I.sreg[CS].selector );
467 			PUSH16( I.eip );
468 		}
469 		I.sreg[CS].selector = ptr;
470 		I.eip = offset;
471 		i386_load_segment_descriptor(CS);
472 	}
473 	CYCLES(CYCLES_CALL_INTERSEG);		/* TODO: Timing = 17 + m */
474 	CHANGE_PC(I.eip);
475 }
476 
I386OP(call_rel16)477 static void I386OP(call_rel16)(void)		// Opcode 0xe8
478 {
479 	INT16 disp = FETCH16();
480 
481 	PUSH16( I.eip );
482 	if (I.sreg[CS].d)
483 	{
484 		I.eip += disp;
485 	}
486 	else
487 	{
488 		I.eip = (I.eip + disp) & 0xffff;
489 	}
490 	CHANGE_PC(I.eip);
491 	CYCLES(CYCLES_CALL);		/* TODO: Timing = 7 + m */
492 }
493 
I386OP(cbw)494 static void I386OP(cbw)(void)				// Opcode 0x98
495 {
496 	REG16(AX) = (INT16)((INT8)REG8(AL));
497 	CYCLES(CYCLES_CBW);
498 }
499 
I386OP(cmp_rm16_r16)500 static void I386OP(cmp_rm16_r16)(void)		// Opcode 0x39
501 {
502 	UINT16 src, dst;
503 	UINT8 modrm = FETCH();
504 	if( modrm >= 0xc0 ) {
505 		src = LOAD_REG16(modrm);
506 		dst = LOAD_RM16(modrm);
507 		SUB16(dst, src);
508 		CYCLES(CYCLES_CMP_REG_REG);
509 	} else {
510 		UINT32 ea = GetEA(modrm);
511 		src = LOAD_REG16(modrm);
512 		dst = READ16(ea);
513 		SUB16(dst, src);
514 		CYCLES(CYCLES_CMP_REG_MEM);
515 	}
516 }
517 
I386OP(cmp_r16_rm16)518 static void I386OP(cmp_r16_rm16)(void)		// Opcode 0x3b
519 {
520 	UINT16 src, dst;
521 	UINT8 modrm = FETCH();
522 	if( modrm >= 0xc0 ) {
523 		src = LOAD_RM16(modrm);
524 		dst = LOAD_REG16(modrm);
525 		SUB16(dst, src);
526 		CYCLES(CYCLES_CMP_REG_REG);
527 	} else {
528 		UINT32 ea = GetEA(modrm);
529 		src = READ16(ea);
530 		dst = LOAD_REG16(modrm);
531 		SUB16(dst, src);
532 		CYCLES(CYCLES_CMP_MEM_REG);
533 	}
534 }
535 
I386OP(cmp_ax_i16)536 static void I386OP(cmp_ax_i16)(void)		// Opcode 0x3d
537 {
538 	UINT16 src, dst;
539 	src = FETCH16();
540 	dst = REG16(AX);
541 	SUB16(dst, src);
542 	CYCLES(CYCLES_CMP_IMM_ACC);
543 }
544 
I386OP(cmpsw)545 static void I386OP(cmpsw)(void)				// Opcode 0xa7
546 {
547 	UINT32 eas, ead;
548 	UINT16 src, dst;
549 	if( I.segment_prefix ) {
550 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
551 	} else {
552 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
553 	}
554 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
555 	src = READ16(eas);
556 	dst = READ16(ead);
557 	SUB16(dst, src);
558 	BUMP_SI(2);
559 	BUMP_DI(2);
560 	CYCLES(CYCLES_CMPS);
561 }
562 
I386OP(cwd)563 static void I386OP(cwd)(void)				// Opcode 0x99
564 {
565 	if( REG16(AX) & 0x8000 ) {
566 		REG16(DX) = 0xffff;
567 	} else {
568 		REG16(DX) = 0x0000;
569 	}
570 	CYCLES(CYCLES_CWD);
571 }
572 
I386OP(dec_ax)573 static void I386OP(dec_ax)(void)			// Opcode 0x48
574 {
575 	REG16(AX) = DEC16( REG16(AX) );
576 	CYCLES(CYCLES_DEC_REG);
577 }
578 
I386OP(dec_cx)579 static void I386OP(dec_cx)(void)			// Opcode 0x49
580 {
581 	REG16(CX) = DEC16( REG16(CX) );
582 	CYCLES(CYCLES_DEC_REG);
583 }
584 
I386OP(dec_dx)585 static void I386OP(dec_dx)(void)			// Opcode 0x4a
586 {
587 	REG16(DX) = DEC16( REG16(DX) );
588 	CYCLES(CYCLES_DEC_REG);
589 }
590 
I386OP(dec_bx)591 static void I386OP(dec_bx)(void)			// Opcode 0x4b
592 {
593 	REG16(BX) = DEC16( REG16(BX) );
594 	CYCLES(CYCLES_DEC_REG);
595 }
596 
I386OP(dec_sp)597 static void I386OP(dec_sp)(void)			// Opcode 0x4c
598 {
599 	REG16(SP) = DEC16( REG16(SP) );
600 	CYCLES(CYCLES_DEC_REG);
601 }
602 
I386OP(dec_bp)603 static void I386OP(dec_bp)(void)			// Opcode 0x4d
604 {
605 	REG16(BP) = DEC16( REG16(BP) );
606 	CYCLES(CYCLES_DEC_REG);
607 }
608 
I386OP(dec_si)609 static void I386OP(dec_si)(void)			// Opcode 0x4e
610 {
611 	REG16(SI) = DEC16( REG16(SI) );
612 	CYCLES(CYCLES_DEC_REG);
613 }
614 
I386OP(dec_di)615 static void I386OP(dec_di)(void)			// Opcode 0x4f
616 {
617 	REG16(DI) = DEC16( REG16(DI) );
618 	CYCLES(CYCLES_DEC_REG);
619 }
620 
I386OP(imul_r16_rm16)621 static void I386OP(imul_r16_rm16)(void)		// Opcode 0x0f af
622 {
623 	UINT8 modrm = FETCH();
624 	INT32 result;
625 	INT32 src, dst;
626 	if( modrm >= 0xc0 ) {
627 		src = (INT32)(INT16)LOAD_RM16(modrm);
628 		CYCLES(CYCLES_IMUL16_REG_REG);		/* TODO: Correct multiply timing */
629 	} else {
630 		UINT32 ea = GetEA(modrm);
631 		src = (INT32)(INT16)READ16(ea);
632 		CYCLES(CYCLES_IMUL16_REG_MEM);		/* TODO: Correct multiply timing */
633 	}
634 
635 	dst = (INT32)(INT16)LOAD_REG16(modrm);
636 	result = src * dst;
637 
638 	STORE_REG16(modrm, (UINT16)result);
639 
640 	I.CF = I.OF = !(result == (INT32)(INT16)result);
641 }
642 
I386OP(imul_r16_rm16_i16)643 static void I386OP(imul_r16_rm16_i16)(void)	// Opcode 0x69
644 {
645 	UINT8 modrm = FETCH();
646 	INT32 result;
647 	INT32 src, dst;
648 	if( modrm >= 0xc0 ) {
649 		dst = (INT32)(INT16)LOAD_RM16(modrm);
650 		CYCLES(CYCLES_IMUL16_REG_IMM_REG);		/* TODO: Correct multiply timing */
651 	} else {
652 		UINT32 ea = GetEA(modrm);
653 		dst = (INT32)(INT16)READ16(ea);
654 		CYCLES(CYCLES_IMUL16_MEM_IMM_REG);		/* TODO: Correct multiply timing */
655 	}
656 
657 	src = (INT32)(INT16)FETCH16();
658 	result = src * dst;
659 
660 	STORE_REG16(modrm, (UINT16)result);
661 
662 	I.CF = I.OF = !(result == (INT32)(INT16)result);
663 }
664 
I386OP(imul_r16_rm16_i8)665 static void I386OP(imul_r16_rm16_i8)(void)	// Opcode 0x6b
666 {
667 	UINT8 modrm = FETCH();
668 	INT32 result;
669 	INT32 src, dst;
670 	if( modrm >= 0xc0 ) {
671 		dst = (INT32)(INT16)LOAD_RM16(modrm);
672 		CYCLES(CYCLES_IMUL16_REG_IMM_REG);		/* TODO: Correct multiply timing */
673 	} else {
674 		UINT32 ea = GetEA(modrm);
675 		dst = (INT32)(INT16)READ16(ea);
676 		CYCLES(CYCLES_IMUL16_MEM_IMM_REG);		/* TODO: Correct multiply timing */
677 	}
678 
679 	src = (INT32)(INT8)FETCH();
680 	result = src * dst;
681 
682 	STORE_REG16(modrm, (UINT16)result);
683 
684 	I.CF = I.OF = !(result == (INT32)(INT16)result);
685 }
686 
I386OP(in_ax_i8)687 static void I386OP(in_ax_i8)(void)			// Opcode 0xe5
688 {
689 	UINT16 port = FETCH();
690 	UINT16 data = READPORT16(port);
691 	REG16(AX) = data;
692 	CYCLES(CYCLES_IN_VAR);
693 }
694 
I386OP(in_ax_dx)695 static void I386OP(in_ax_dx)(void)			// Opcode 0xed
696 {
697 	UINT16 port = REG16(DX);
698 	UINT16 data = READPORT16(port);
699 	REG16(AX) = data;
700 	CYCLES(CYCLES_IN);
701 }
702 
I386OP(inc_ax)703 static void I386OP(inc_ax)(void)			// Opcode 0x40
704 {
705 	REG16(AX) = INC16( REG16(AX) );
706 	CYCLES(CYCLES_INC_REG);
707 }
708 
I386OP(inc_cx)709 static void I386OP(inc_cx)(void)			// Opcode 0x41
710 {
711 	REG16(CX) = INC16( REG16(CX) );
712 	CYCLES(CYCLES_INC_REG);
713 }
714 
I386OP(inc_dx)715 static void I386OP(inc_dx)(void)			// Opcode 0x42
716 {
717 	REG16(DX) = INC16( REG16(DX) );
718 	CYCLES(CYCLES_INC_REG);
719 }
720 
I386OP(inc_bx)721 static void I386OP(inc_bx)(void)			// Opcode 0x43
722 {
723 	REG16(BX) = INC16( REG16(BX) );
724 	CYCLES(CYCLES_INC_REG);
725 }
726 
I386OP(inc_sp)727 static void I386OP(inc_sp)(void)			// Opcode 0x44
728 {
729 	REG16(SP) = INC16( REG16(SP) );
730 	CYCLES(CYCLES_INC_REG);
731 }
732 
I386OP(inc_bp)733 static void I386OP(inc_bp)(void)			// Opcode 0x45
734 {
735 	REG16(BP) = INC16( REG16(BP) );
736 	CYCLES(CYCLES_INC_REG);
737 }
738 
I386OP(inc_si)739 static void I386OP(inc_si)(void)			// Opcode 0x46
740 {
741 	REG16(SI) = INC16( REG16(SI) );
742 	CYCLES(CYCLES_INC_REG);
743 }
744 
I386OP(inc_di)745 static void I386OP(inc_di)(void)			// Opcode 0x47
746 {
747 	REG16(DI) = INC16( REG16(DI) );
748 	CYCLES(CYCLES_INC_REG);
749 }
750 
I386OP(iret16)751 static void I386OP(iret16)(void)			// Opcode 0xcf
752 {
753 	if( PROTECTED_MODE ) {
754 		/* TODO: Virtual 8086-mode */
755 		/* TODO: Nested task */
756 		/* TODO: #SS(0) exception */
757 		/* TODO: All the protection-related stuff... */
758 		I.eip = POP16();
759 		I.sreg[CS].selector = POP16();
760 		set_flags( POP16() );
761 		i386_load_segment_descriptor(CS);
762 		CHANGE_PC(I.eip);
763 	} else {
764 		/* TODO: #SS(0) exception */
765 		/* TODO: #GP(0) exception */
766 		I.eip = POP16();
767 		I.sreg[CS].selector = POP16();
768 		set_flags( POP16() );
769 		i386_load_segment_descriptor(CS);
770 		CHANGE_PC(I.eip);
771 	}
772 	CYCLES(CYCLES_IRET);
773 }
774 
I386OP(ja_rel16)775 static void I386OP(ja_rel16)(void)			// Opcode 0x0f 87
776 {
777 	INT16 disp = FETCH16();
778 	if( I.CF == 0 && I.ZF == 0 ) {
779 		if (I.sreg[CS].d)
780 		{
781 			I.eip += disp;
782 		}
783 		else
784 		{
785 			I.eip = (I.eip + disp) & 0xffff;
786 		}
787 		CHANGE_PC(I.eip);
788 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
789 	} else {
790 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
791 	}
792 }
793 
I386OP(jbe_rel16)794 static void I386OP(jbe_rel16)(void)			// Opcode 0x0f 86
795 {
796 	INT16 disp = FETCH16();
797 	if( I.CF != 0 || I.ZF != 0 ) {
798 		if (I.sreg[CS].d)
799 		{
800 			I.eip += disp;
801 		}
802 		else
803 		{
804 			I.eip = (I.eip + disp) & 0xffff;
805 		}
806 		CHANGE_PC(I.eip);
807 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
808 	} else {
809 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
810 	}
811 }
812 
I386OP(jc_rel16)813 static void I386OP(jc_rel16)(void)			// Opcode 0x0f 82
814 {
815 	INT16 disp = FETCH16();
816 	if( I.CF != 0 ) {
817 		if (I.sreg[CS].d)
818 		{
819 			I.eip += disp;
820 		}
821 		else
822 		{
823 			I.eip = (I.eip + disp) & 0xffff;
824 		}
825 		CHANGE_PC(I.eip);
826 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
827 	} else {
828 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
829 	}
830 }
831 
I386OP(jg_rel16)832 static void I386OP(jg_rel16)(void)			// Opcode 0x0f 8f
833 {
834 	INT16 disp = FETCH16();
835 	if( I.ZF == 0 && (I.SF == I.OF) ) {
836 		if (I.sreg[CS].d)
837 		{
838 			I.eip += disp;
839 		}
840 		else
841 		{
842 			I.eip = (I.eip + disp) & 0xffff;
843 		}
844 		CHANGE_PC(I.eip);
845 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
846 	} else {
847 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
848 	}
849 }
850 
I386OP(jge_rel16)851 static void I386OP(jge_rel16)(void)			// Opcode 0x0f 8d
852 {
853 	INT16 disp = FETCH16();
854 	if( (I.SF == I.OF) ) {
855 		if (I.sreg[CS].d)
856 		{
857 			I.eip += disp;
858 		}
859 		else
860 		{
861 			I.eip = (I.eip + disp) & 0xffff;
862 		}
863 		CHANGE_PC(I.eip);
864 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
865 	} else {
866 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
867 	}
868 }
869 
I386OP(jl_rel16)870 static void I386OP(jl_rel16)(void)			// Opcode 0x0f 8c
871 {
872 	INT16 disp = FETCH16();
873 	if( (I.SF != I.OF) ) {
874 		if (I.sreg[CS].d)
875 		{
876 			I.eip += disp;
877 		}
878 		else
879 		{
880 			I.eip = (I.eip + disp) & 0xffff;
881 		}
882 		CHANGE_PC(I.eip);
883 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
884 	} else {
885 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
886 	}
887 }
888 
I386OP(jle_rel16)889 static void I386OP(jle_rel16)(void)			// Opcode 0x0f 8e
890 {
891 	INT16 disp = FETCH16();
892 	if( I.ZF != 0 || (I.SF != I.OF) ) {
893 		if (I.sreg[CS].d)
894 		{
895 			I.eip += disp;
896 		}
897 		else
898 		{
899 			I.eip = (I.eip + disp) & 0xffff;
900 		}
901 		CHANGE_PC(I.eip);
902 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
903 	} else {
904 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
905 	}
906 }
907 
I386OP(jnc_rel16)908 static void I386OP(jnc_rel16)(void)			// Opcode 0x0f 83
909 {
910 	INT16 disp = FETCH16();
911 	if( I.CF == 0 ) {
912 		if (I.sreg[CS].d)
913 		{
914 			I.eip += disp;
915 		}
916 		else
917 		{
918 			I.eip = (I.eip + disp) & 0xffff;
919 		}
920 		CHANGE_PC(I.eip);
921 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
922 	} else {
923 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
924 	}
925 }
926 
I386OP(jno_rel16)927 static void I386OP(jno_rel16)(void)			// Opcode 0x0f 81
928 {
929 	INT16 disp = FETCH16();
930 	if( I.OF == 0 ) {
931 		if (I.sreg[CS].d)
932 		{
933 			I.eip += disp;
934 		}
935 		else
936 		{
937 			I.eip = (I.eip + disp) & 0xffff;
938 		}
939 		CHANGE_PC(I.eip);
940 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
941 	} else {
942 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
943 	}
944 }
945 
I386OP(jnp_rel16)946 static void I386OP(jnp_rel16)(void)			// Opcode 0x0f 8b
947 {
948 	INT16 disp = FETCH16();
949 	if( I.PF == 0 ) {
950 		if (I.sreg[CS].d)
951 		{
952 			I.eip += disp;
953 		}
954 		else
955 		{
956 			I.eip = (I.eip + disp) & 0xffff;
957 		}
958 		CHANGE_PC(I.eip);
959 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
960 	} else {
961 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
962 	}
963 }
964 
I386OP(jns_rel16)965 static void I386OP(jns_rel16)(void)			// Opcode 0x0f 89
966 {
967 	INT16 disp = FETCH16();
968 	if( I.SF == 0 ) {
969 		if (I.sreg[CS].d)
970 		{
971 			I.eip += disp;
972 		}
973 		else
974 		{
975 			I.eip = (I.eip + disp) & 0xffff;
976 		}
977 		CHANGE_PC(I.eip);
978 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
979 	} else {
980 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
981 	}
982 }
983 
I386OP(jnz_rel16)984 static void I386OP(jnz_rel16)(void)			// Opcode 0x0f 85
985 {
986 	INT16 disp = FETCH16();
987 	if( I.ZF == 0 ) {
988 		if (I.sreg[CS].d)
989 		{
990 			I.eip += disp;
991 		}
992 		else
993 		{
994 			I.eip = (I.eip + disp) & 0xffff;
995 		}
996 		CHANGE_PC(I.eip);
997 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
998 	} else {
999 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1000 	}
1001 }
1002 
I386OP(jo_rel16)1003 static void I386OP(jo_rel16)(void)			// Opcode 0x0f 80
1004 {
1005 	INT16 disp = FETCH16();
1006 	if( I.OF != 0 ) {
1007 		if (I.sreg[CS].d)
1008 		{
1009 			I.eip += disp;
1010 		}
1011 		else
1012 		{
1013 			I.eip = (I.eip + disp) & 0xffff;
1014 		}
1015 		CHANGE_PC(I.eip);
1016 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
1017 	} else {
1018 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1019 	}
1020 }
1021 
I386OP(jp_rel16)1022 static void I386OP(jp_rel16)(void)			// Opcode 0x0f 8a
1023 {
1024 	INT16 disp = FETCH16();
1025 	if( I.PF != 0 ) {
1026 		if (I.sreg[CS].d)
1027 		{
1028 			I.eip += disp;
1029 		}
1030 		else
1031 		{
1032 			I.eip = (I.eip + disp) & 0xffff;
1033 		}
1034 		CHANGE_PC(I.eip);
1035 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
1036 	} else {
1037 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1038 	}
1039 }
1040 
I386OP(js_rel16)1041 static void I386OP(js_rel16)(void)			// Opcode 0x0f 88
1042 {
1043 	INT16 disp = FETCH16();
1044 	if( I.SF != 0 ) {
1045 		if (I.sreg[CS].d)
1046 		{
1047 			I.eip += disp;
1048 		}
1049 		else
1050 		{
1051 			I.eip = (I.eip + disp) & 0xffff;
1052 		}
1053 		CHANGE_PC(I.eip);
1054 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
1055 	} else {
1056 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1057 	}
1058 }
1059 
I386OP(jz_rel16)1060 static void I386OP(jz_rel16)(void)			// Opcode 0x0f 84
1061 {
1062 	INT16 disp = FETCH16();
1063 	if( I.ZF != 0 ) {
1064 		if (I.sreg[CS].d)
1065 		{
1066 			I.eip += disp;
1067 		}
1068 		else
1069 		{
1070 			I.eip = (I.eip + disp) & 0xffff;
1071 		}
1072 		CHANGE_PC(I.eip);
1073 		CYCLES(CYCLES_JCC_FULL_DISP);		/* TODO: Timing = 7 + m */
1074 	} else {
1075 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1076 	}
1077 }
1078 
I386OP(jcxz16)1079 static void I386OP(jcxz16)(void)			// Opcode 0xe3
1080 {
1081 	INT8 disp = FETCH();
1082 	if( REG16(CX) == 0 ) {
1083 		if (I.sreg[CS].d)
1084 		{
1085 			I.eip += disp;
1086 		}
1087 		else
1088 		{
1089 			I.eip = (I.eip + disp) & 0xffff;
1090 		}
1091 		CHANGE_PC(I.eip);
1092 		CYCLES(CYCLES_JCXZ);		/* TODO: Timing = 9 + m */
1093 	} else {
1094 		CYCLES(CYCLES_JCXZ_NOBRANCH);
1095 	}
1096 }
1097 
I386OP(jmp_rel16)1098 static void I386OP(jmp_rel16)(void)			// Opcode 0xe9
1099 {
1100 	INT16 disp = FETCH16();
1101 
1102 	if (I.sreg[CS].d)
1103 	{
1104 		I.eip += disp;
1105 	}
1106 	else
1107 	{
1108 		I.eip = (I.eip + disp) & 0xffff;
1109 	}
1110 	CHANGE_PC(I.eip);
1111 	CYCLES(CYCLES_JMP);		/* TODO: Timing = 7 + m */
1112 }
1113 
I386OP(jmp_abs16)1114 static void I386OP(jmp_abs16)(void)			// Opcode 0xea
1115 {
1116 	UINT16 address = FETCH16();
1117 	UINT16 segment = FETCH16();
1118 
1119 	if( PROTECTED_MODE ) {
1120 		/* TODO: #GP */
1121 		/* TODO: access rights, etc. */
1122 		I.eip = address;
1123 		I.sreg[CS].selector = segment;
1124 		I.performed_intersegment_jump = 1;
1125 		i386_load_segment_descriptor(CS);
1126 		CHANGE_PC(I.eip);
1127 	} else {
1128 		I.eip = address;
1129 		I.sreg[CS].selector = segment;
1130 		I.performed_intersegment_jump = 1;
1131 		i386_load_segment_descriptor(CS);
1132 		CHANGE_PC(I.eip);
1133 	}
1134 	CYCLES(CYCLES_JMP_INTERSEG);
1135 }
1136 
I386OP(lea16)1137 static void I386OP(lea16)(void)				// Opcode 0x8d
1138 {
1139 	UINT8 modrm = FETCH();
1140 	UINT32 ea = GetNonTranslatedEA(modrm);
1141 	STORE_REG16(modrm, ea);
1142 	CYCLES(CYCLES_LEA);
1143 }
1144 
I386OP(leave16)1145 static void I386OP(leave16)(void)			// Opcode 0xc9
1146 {
1147 	REG16(SP) = REG16(BP);
1148 	REG16(BP) = POP16();
1149 	CYCLES(CYCLES_LEAVE);
1150 }
1151 
I386OP(lodsw)1152 static void I386OP(lodsw)(void)				// Opcode 0xad
1153 {
1154 	UINT32 eas;
1155 	if( I.segment_prefix ) {
1156 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
1157 	} else {
1158 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
1159 	}
1160 	REG16(AX) = READ16(eas);
1161 	BUMP_SI(2);
1162 	CYCLES(CYCLES_LODS);
1163 }
1164 
I386OP(loop16)1165 static void I386OP(loop16)(void)			// Opcode 0xe2
1166 {
1167 	INT8 disp = FETCH();
1168 	REG16(CX)--;
1169 	if( REG16(CX) != 0 ) {
1170 		if (I.sreg[CS].d)
1171 		{
1172 			I.eip += disp;
1173 		}
1174 		else
1175 		{
1176 			I.eip = (I.eip + disp) & 0xffff;
1177 		}
1178 		CHANGE_PC(I.eip);
1179 	}
1180 	CYCLES(CYCLES_LOOP);		/* TODO: Timing = 11 + m */
1181 }
1182 
I386OP(loopne16)1183 static void I386OP(loopne16)(void)			// Opcode 0xe0
1184 {
1185 	INT8 disp = FETCH();
1186 	REG16(CX)--;
1187 	if( REG16(CX) != 0 && I.ZF == 0 ) {
1188 		if (I.sreg[CS].d)
1189 		{
1190 			I.eip += disp;
1191 		}
1192 		else
1193 		{
1194 			I.eip = (I.eip + disp) & 0xffff;
1195 		}
1196 		CHANGE_PC(I.eip);
1197 	}
1198 	CYCLES(CYCLES_LOOPNZ);		/* TODO: Timing = 11 + m */
1199 }
1200 
I386OP(loopz16)1201 static void I386OP(loopz16)(void)			// Opcode 0xe1
1202 {
1203 	INT8 disp = FETCH();
1204 	REG16(CX)--;
1205 	if( REG16(CX) != 0 && I.ZF != 0 ) {
1206 		if (I.sreg[CS].d)
1207 		{
1208 			I.eip += disp;
1209 		}
1210 		else
1211 		{
1212 			I.eip = (I.eip + disp) & 0xffff;
1213 		}
1214 		CHANGE_PC(I.eip);
1215 	}
1216 	CYCLES(CYCLES_LOOPZ);		/* TODO: Timing = 11 + m */
1217 }
1218 
I386OP(mov_rm16_r16)1219 static void I386OP(mov_rm16_r16)(void)		// Opcode 0x89
1220 {
1221 	UINT16 src;
1222 	UINT8 modrm = FETCH();
1223 	if( modrm >= 0xc0 ) {
1224 		src = LOAD_REG16(modrm);
1225 		STORE_RM16(modrm, src);
1226 		CYCLES(CYCLES_MOV_REG_REG);
1227 	} else {
1228 		UINT32 ea = GetEA(modrm);
1229 		src = LOAD_REG16(modrm);
1230 		WRITE16(ea, src);
1231 		CYCLES(CYCLES_MOV_REG_MEM);
1232 	}
1233 }
1234 
I386OP(mov_r16_rm16)1235 static void I386OP(mov_r16_rm16)(void)		// Opcode 0x8b
1236 {
1237 	UINT16 src;
1238 	UINT8 modrm = FETCH();
1239 	if( modrm >= 0xc0 ) {
1240 		src = LOAD_RM16(modrm);
1241 		STORE_REG16(modrm, src);
1242 		CYCLES(CYCLES_MOV_REG_REG);
1243 	} else {
1244 		UINT32 ea = GetEA(modrm);
1245 		src = READ16(ea);
1246 		STORE_REG16(modrm, src);
1247 		CYCLES(CYCLES_MOV_MEM_REG);
1248 	}
1249 }
1250 
I386OP(mov_rm16_i16)1251 static void I386OP(mov_rm16_i16)(void)		// Opcode 0xc7
1252 {
1253 	UINT8 modrm = FETCH();
1254 	if( modrm >= 0xc0 ) {
1255 		UINT16 value = FETCH16();
1256 		STORE_RM16(modrm, value);
1257 		CYCLES(CYCLES_MOV_IMM_REG);
1258 	} else {
1259 		UINT32 ea = GetEA(modrm);
1260 		UINT16 value = FETCH16();
1261 		WRITE16(ea, value);
1262 		CYCLES(CYCLES_MOV_IMM_MEM);
1263 	}
1264 }
1265 
I386OP(mov_ax_m16)1266 static void I386OP(mov_ax_m16)(void)		// Opcode 0xa1
1267 {
1268 	UINT32 offset, ea;
1269 	if( I.address_size ) {
1270 		offset = FETCH32();
1271 	} else {
1272 		offset = FETCH16();
1273 	}
1274 	/* TODO: Not sure if this is correct... */
1275 	if( I.segment_prefix ) {
1276 		ea = i386_translate( I.segment_override, offset );
1277 	} else {
1278 		ea = i386_translate( DS, offset );
1279 	}
1280 	REG16(AX) = READ16(ea);
1281 	CYCLES(CYCLES_MOV_MEM_ACC);
1282 }
1283 
I386OP(mov_m16_ax)1284 static void I386OP(mov_m16_ax)(void)		// Opcode 0xa3
1285 {
1286 	UINT32 offset, ea;
1287 	if( I.address_size ) {
1288 		offset = FETCH32();
1289 	} else {
1290 		offset = FETCH16();
1291 	}
1292 	/* TODO: Not sure if this is correct... */
1293 	if( I.segment_prefix ) {
1294 		ea = i386_translate( I.segment_override, offset );
1295 	} else {
1296 		ea = i386_translate( DS, offset );
1297 	}
1298 	WRITE16( ea, REG16(AX) );
1299 	CYCLES(CYCLES_MOV_ACC_MEM);
1300 }
1301 
I386OP(mov_ax_i16)1302 static void I386OP(mov_ax_i16)(void)		// Opcode 0xb8
1303 {
1304 	REG16(AX) = FETCH16();
1305 	CYCLES(CYCLES_MOV_IMM_REG);
1306 }
1307 
I386OP(mov_cx_i16)1308 static void I386OP(mov_cx_i16)(void)		// Opcode 0xb9
1309 {
1310 	REG16(CX) = FETCH16();
1311 	CYCLES(CYCLES_MOV_IMM_REG);
1312 }
1313 
I386OP(mov_dx_i16)1314 static void I386OP(mov_dx_i16)(void)		// Opcode 0xba
1315 {
1316 	REG16(DX) = FETCH16();
1317 	CYCLES(CYCLES_MOV_IMM_REG);
1318 }
1319 
I386OP(mov_bx_i16)1320 static void I386OP(mov_bx_i16)(void)		// Opcode 0xbb
1321 {
1322 	REG16(BX) = FETCH16();
1323 	CYCLES(CYCLES_MOV_IMM_REG);
1324 }
1325 
I386OP(mov_sp_i16)1326 static void I386OP(mov_sp_i16)(void)		// Opcode 0xbc
1327 {
1328 	REG16(SP) = FETCH16();
1329 	CYCLES(CYCLES_MOV_IMM_REG);
1330 }
1331 
I386OP(mov_bp_i16)1332 static void I386OP(mov_bp_i16)(void)		// Opcode 0xbd
1333 {
1334 	REG16(BP) = FETCH16();
1335 	CYCLES(CYCLES_MOV_IMM_REG);
1336 }
1337 
I386OP(mov_si_i16)1338 static void I386OP(mov_si_i16)(void)		// Opcode 0xbe
1339 {
1340 	REG16(SI) = FETCH16();
1341 	CYCLES(CYCLES_MOV_IMM_REG);
1342 }
1343 
I386OP(mov_di_i16)1344 static void I386OP(mov_di_i16)(void)		// Opcode 0xbf
1345 {
1346 	REG16(DI) = FETCH16();
1347 	CYCLES(CYCLES_MOV_IMM_REG);
1348 }
1349 
I386OP(movsw)1350 static void I386OP(movsw)(void)				// Opcode 0xa5
1351 {
1352 	UINT32 eas, ead;
1353 	UINT16 v;
1354 	if( I.segment_prefix ) {
1355 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
1356 	} else {
1357 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
1358 	}
1359 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1360 	v = READ16(eas);
1361 	WRITE16(ead, v);
1362 	BUMP_SI(2);
1363 	BUMP_DI(2);
1364 	CYCLES(CYCLES_MOVS);
1365 }
1366 
I386OP(movsx_r16_rm8)1367 static void I386OP(movsx_r16_rm8)(void)		// Opcode 0x0f be
1368 {
1369 	UINT8 modrm = FETCH();
1370 	if( modrm >= 0xc0 ) {
1371 		INT16 src = (INT8)LOAD_RM8(modrm);
1372 		STORE_REG16(modrm, src);
1373 		CYCLES(CYCLES_MOVSX_REG_REG);
1374 	} else {
1375 		UINT32 ea = GetEA(modrm);
1376 		INT16 src = (INT8)READ8(ea);
1377 		STORE_REG16(modrm, src);
1378 		CYCLES(CYCLES_MOVSX_MEM_REG);
1379 	}
1380 }
1381 
I386OP(movzx_r16_rm8)1382 static void I386OP(movzx_r16_rm8)(void)		// Opcode 0x0f b6
1383 {
1384 	UINT8 modrm = FETCH();
1385 	if( modrm >= 0xc0 ) {
1386 		UINT16 src = (UINT8)LOAD_RM8(modrm);
1387 		STORE_REG16(modrm, src);
1388 		CYCLES(CYCLES_MOVZX_REG_REG);
1389 	} else {
1390 		UINT32 ea = GetEA(modrm);
1391 		UINT16 src = (UINT8)READ8(ea);
1392 		STORE_REG16(modrm, src);
1393 		CYCLES(CYCLES_MOVZX_MEM_REG);
1394 	}
1395 }
1396 
I386OP(or_rm16_r16)1397 static void I386OP(or_rm16_r16)(void)		// Opcode 0x09
1398 {
1399 	UINT16 src, dst;
1400 	UINT8 modrm = FETCH();
1401 	if( modrm >= 0xc0 ) {
1402 		src = LOAD_REG16(modrm);
1403 		dst = LOAD_RM16(modrm);
1404 		dst = OR16(dst, src);
1405 		STORE_RM16(modrm, dst);
1406 		CYCLES(CYCLES_ALU_REG_REG);
1407 	} else {
1408 		UINT32 ea = GetEA(modrm);
1409 		src = LOAD_REG16(modrm);
1410 		dst = READ16(ea);
1411 		dst = OR16(dst, src);
1412 		WRITE16(ea, dst);
1413 		CYCLES(CYCLES_ALU_REG_MEM);
1414 	}
1415 }
1416 
I386OP(or_r16_rm16)1417 static void I386OP(or_r16_rm16)(void)		// Opcode 0x0b
1418 {
1419 	UINT16 src, dst;
1420 	UINT8 modrm = FETCH();
1421 	if( modrm >= 0xc0 ) {
1422 		src = LOAD_RM16(modrm);
1423 		dst = LOAD_REG16(modrm);
1424 		dst = OR16(dst, src);
1425 		STORE_REG16(modrm, dst);
1426 		CYCLES(CYCLES_ALU_REG_REG);
1427 	} else {
1428 		UINT32 ea = GetEA(modrm);
1429 		src = READ16(ea);
1430 		dst = LOAD_REG16(modrm);
1431 		dst = OR16(dst, src);
1432 		STORE_REG16(modrm, dst);
1433 		CYCLES(CYCLES_ALU_MEM_REG);
1434 	}
1435 }
1436 
I386OP(or_ax_i16)1437 static void I386OP(or_ax_i16)(void)			// Opcode 0x0d
1438 {
1439 	UINT16 src, dst;
1440 	src = FETCH16();
1441 	dst = REG16(AX);
1442 	dst = OR16(dst, src);
1443 	REG16(AX) = dst;
1444 	CYCLES(CYCLES_ALU_IMM_ACC);
1445 }
1446 
I386OP(out_ax_i8)1447 static void I386OP(out_ax_i8)(void)			// Opcode 0xe7
1448 {
1449 	UINT16 port = FETCH();
1450 	UINT16 data = REG16(AX);
1451 	WRITEPORT16(port, data);
1452 	CYCLES(CYCLES_OUT_VAR);
1453 }
1454 
I386OP(out_ax_dx)1455 static void I386OP(out_ax_dx)(void)			// Opcode 0xef
1456 {
1457 	UINT16 port = REG16(DX);
1458 	UINT16 data = REG16(AX);
1459 	WRITEPORT16(port, data);
1460 	CYCLES(CYCLES_OUT);
1461 }
1462 
I386OP(pop_ax)1463 static void I386OP(pop_ax)(void)			// Opcode 0x58
1464 {
1465 	REG16(AX) = POP16();
1466 	CYCLES(CYCLES_POP_REG_SHORT);
1467 }
1468 
I386OP(pop_cx)1469 static void I386OP(pop_cx)(void)			// Opcode 0x59
1470 {
1471 	REG16(CX) = POP16();
1472 	CYCLES(CYCLES_POP_REG_SHORT);
1473 }
1474 
I386OP(pop_dx)1475 static void I386OP(pop_dx)(void)			// Opcode 0x5a
1476 {
1477 	REG16(DX) = POP16();
1478 	CYCLES(CYCLES_POP_REG_SHORT);
1479 }
1480 
I386OP(pop_bx)1481 static void I386OP(pop_bx)(void)			// Opcode 0x5b
1482 {
1483 	REG16(BX) = POP16();
1484 	CYCLES(CYCLES_POP_REG_SHORT);
1485 }
1486 
I386OP(pop_sp)1487 static void I386OP(pop_sp)(void)			// Opcode 0x5c
1488 {
1489 	REG16(SP) = POP16();
1490 	CYCLES(CYCLES_POP_REG_SHORT);
1491 }
1492 
I386OP(pop_bp)1493 static void I386OP(pop_bp)(void)			// Opcode 0x5d
1494 {
1495 	REG16(BP) = POP16();
1496 	CYCLES(CYCLES_POP_REG_SHORT);
1497 }
1498 
I386OP(pop_si)1499 static void I386OP(pop_si)(void)			// Opcode 0x5e
1500 {
1501 	REG16(SI) = POP16();
1502 	CYCLES(CYCLES_POP_REG_SHORT);
1503 }
1504 
I386OP(pop_di)1505 static void I386OP(pop_di)(void)			// Opcode 0x5f
1506 {
1507 	REG16(DI) = POP16();
1508 	CYCLES(CYCLES_POP_REG_SHORT);
1509 }
1510 
I386OP(pop_ds16)1511 static void I386OP(pop_ds16)(void)			// Opcode 0x1f
1512 {
1513 	I.sreg[DS].selector = POP16();
1514 	if( PROTECTED_MODE ) {
1515 		i386_load_segment_descriptor(DS);
1516 	} else {
1517 		i386_load_segment_descriptor(DS);
1518 	}
1519 	CYCLES(CYCLES_POP_SREG);
1520 }
1521 
I386OP(pop_es16)1522 static void I386OP(pop_es16)(void)			// Opcode 0x07
1523 {
1524 	I.sreg[ES].selector = POP16();
1525 	if( PROTECTED_MODE ) {
1526 		i386_load_segment_descriptor(ES);
1527 	} else {
1528 		i386_load_segment_descriptor(ES);
1529 	}
1530 	CYCLES(CYCLES_POP_SREG);
1531 }
1532 
I386OP(pop_fs16)1533 static void I386OP(pop_fs16)(void)			// Opcode 0x0f a1
1534 {
1535 	I.sreg[FS].selector = POP16();
1536 	if( PROTECTED_MODE ) {
1537 		i386_load_segment_descriptor(FS);
1538 	} else {
1539 		i386_load_segment_descriptor(FS);
1540 	}
1541 	CYCLES(CYCLES_POP_SREG);
1542 }
1543 
I386OP(pop_gs16)1544 static void I386OP(pop_gs16)(void)			// Opcode 0x0f a9
1545 {
1546 	I.sreg[GS].selector = POP16();
1547 	if( PROTECTED_MODE ) {
1548 		i386_load_segment_descriptor(GS);
1549 	} else {
1550 		i386_load_segment_descriptor(GS);
1551 	}
1552 	CYCLES(CYCLES_POP_SREG);
1553 }
1554 
I386OP(pop_ss16)1555 static void I386OP(pop_ss16)(void)			// Opcode 0x17
1556 {
1557 	I.sreg[SS].selector = POP16();
1558 	if( PROTECTED_MODE ) {
1559 		i386_load_segment_descriptor(SS);
1560 	} else {
1561 		i386_load_segment_descriptor(SS);
1562 	}
1563 	CYCLES(CYCLES_POP_SREG);
1564 }
1565 
I386OP(pop_rm16)1566 static void I386OP(pop_rm16)(void)			// Opcode 0x8f
1567 {
1568 	UINT8 modrm = FETCH();
1569 	UINT16 value = POP16();
1570 
1571 	if( modrm >= 0xc0 ) {
1572 		STORE_RM16(modrm, value);
1573 	} else {
1574 		UINT32 ea = GetEA(modrm);
1575 		WRITE16(ea, value);
1576 	}
1577 	CYCLES(CYCLES_POP_RM);
1578 }
1579 
I386OP(popa)1580 static void I386OP(popa)(void)				// Opcode 0x61
1581 {
1582 	REG16(DI) = POP16();
1583 	REG16(SI) = POP16();
1584 	REG16(BP) = POP16();
1585 	REG16(SP) += 2;
1586 	REG16(BX) = POP16();
1587 	REG16(DX) = POP16();
1588 	REG16(CX) = POP16();
1589 	REG16(AX) = POP16();
1590 	CYCLES(CYCLES_POPA);
1591 }
1592 
I386OP(popf)1593 static void I386OP(popf)(void)				// Opcode 0x9d
1594 {
1595 	UINT16 value = POP16();
1596 	set_flags(value);
1597 	CYCLES(CYCLES_POPF);
1598 }
1599 
I386OP(push_ax)1600 static void I386OP(push_ax)(void)			// Opcode 0x50
1601 {
1602 	PUSH16( REG16(AX) );
1603 	CYCLES(CYCLES_PUSH_REG_SHORT);
1604 }
1605 
I386OP(push_cx)1606 static void I386OP(push_cx)(void)			// Opcode 0x51
1607 {
1608 	PUSH16( REG16(CX) );
1609 	CYCLES(CYCLES_PUSH_REG_SHORT);
1610 }
1611 
I386OP(push_dx)1612 static void I386OP(push_dx)(void)			// Opcode 0x52
1613 {
1614 	PUSH16( REG16(DX) );
1615 	CYCLES(CYCLES_PUSH_REG_SHORT);
1616 }
1617 
I386OP(push_bx)1618 static void I386OP(push_bx)(void)			// Opcode 0x53
1619 {
1620 	PUSH16( REG16(BX) );
1621 	CYCLES(CYCLES_PUSH_REG_SHORT);
1622 }
1623 
I386OP(push_sp)1624 static void I386OP(push_sp)(void)			// Opcode 0x54
1625 {
1626 	PUSH16( REG16(SP) );
1627 	CYCLES(CYCLES_PUSH_REG_SHORT);
1628 }
1629 
I386OP(push_bp)1630 static void I386OP(push_bp)(void)			// Opcode 0x55
1631 {
1632 	PUSH16( REG16(BP) );
1633 	CYCLES(CYCLES_PUSH_REG_SHORT);
1634 }
1635 
I386OP(push_si)1636 static void I386OP(push_si)(void)			// Opcode 0x56
1637 {
1638 	PUSH16( REG16(SI) );
1639 	CYCLES(CYCLES_PUSH_REG_SHORT);
1640 }
1641 
I386OP(push_di)1642 static void I386OP(push_di)(void)			// Opcode 0x57
1643 {
1644 	PUSH16( REG16(DI) );
1645 	CYCLES(CYCLES_PUSH_REG_SHORT);
1646 }
1647 
I386OP(push_cs16)1648 static void I386OP(push_cs16)(void)			// Opcode 0x0e
1649 {
1650 	PUSH16( I.sreg[CS].selector );
1651 	CYCLES(CYCLES_PUSH_SREG);
1652 }
1653 
I386OP(push_ds16)1654 static void I386OP(push_ds16)(void)			// Opcode 0x1e
1655 {
1656 	PUSH16( I.sreg[DS].selector );
1657 	CYCLES(CYCLES_PUSH_SREG);
1658 }
1659 
I386OP(push_es16)1660 static void I386OP(push_es16)(void)			// Opcode 0x06
1661 {
1662 	PUSH16( I.sreg[ES].selector );
1663 	CYCLES(CYCLES_PUSH_SREG);
1664 }
1665 
I386OP(push_fs16)1666 static void I386OP(push_fs16)(void)			// Opcode 0x0f a0
1667 {
1668 	PUSH16( I.sreg[FS].selector );
1669 	CYCLES(CYCLES_PUSH_SREG);
1670 }
1671 
I386OP(push_gs16)1672 static void I386OP(push_gs16)(void)			// Opcode 0x0f a8
1673 {
1674 	PUSH16( I.sreg[GS].selector );
1675 	CYCLES(CYCLES_PUSH_SREG);
1676 }
1677 
I386OP(push_ss16)1678 static void I386OP(push_ss16)(void)			// Opcode 0x16
1679 {
1680 	PUSH16( I.sreg[SS].selector );
1681 	CYCLES(CYCLES_PUSH_SREG);
1682 }
1683 
I386OP(push_i16)1684 static void I386OP(push_i16)(void)			// Opcode 0x68
1685 {
1686 	UINT16 value = FETCH16();
1687 	PUSH16(value);
1688 	CYCLES(CYCLES_PUSH_IMM);
1689 }
1690 
I386OP(pusha)1691 static void I386OP(pusha)(void)				// Opcode 0x60
1692 {
1693 	UINT16 temp = REG16(SP);
1694 	PUSH16( REG16(AX) );
1695 	PUSH16( REG16(CX) );
1696 	PUSH16( REG16(DX) );
1697 	PUSH16( REG16(BX) );
1698 	PUSH16( temp );
1699 	PUSH16( REG16(BP) );
1700 	PUSH16( REG16(SI) );
1701 	PUSH16( REG16(DI) );
1702 	CYCLES(CYCLES_PUSHA);
1703 }
1704 
I386OP(pushf)1705 static void I386OP(pushf)(void)				// Opcode 0x9c
1706 {
1707 	PUSH16( get_flags() & 0xffff );
1708 	CYCLES(CYCLES_PUSHF);
1709 }
1710 
I386OP(ret_near16_i16)1711 static void I386OP(ret_near16_i16)(void)	// Opcode 0xc2
1712 {
1713 	INT16 disp = FETCH16();
1714 	I.eip = POP16();
1715 	REG16(SP) += disp;
1716 	CHANGE_PC(I.eip);
1717 	CYCLES(CYCLES_RET_IMM);		/* TODO: Timing = 10 + m */
1718 }
1719 
I386OP(ret_near16)1720 static void I386OP(ret_near16)(void)		// Opcode 0xc3
1721 {
1722 	I.eip = POP16();
1723 	CHANGE_PC(I.eip);
1724 	CYCLES(CYCLES_RET);		/* TODO: Timing = 10 + m */
1725 }
1726 
I386OP(sbb_rm16_r16)1727 static void I386OP(sbb_rm16_r16)(void)		// Opcode 0x19
1728 {
1729 	UINT16 src, dst;
1730 	UINT8 modrm = FETCH();
1731 	if( modrm >= 0xc0 ) {
1732 		src = LOAD_REG16(modrm) + I.CF;
1733 		dst = LOAD_RM16(modrm);
1734 		dst = SUB16(dst, src);
1735 		STORE_RM16(modrm, dst);
1736 		CYCLES(CYCLES_ALU_REG_REG);
1737 	} else {
1738 		UINT32 ea = GetEA(modrm);
1739 		src = LOAD_REG16(modrm) + I.CF;
1740 		dst = READ16(ea);
1741 		dst = SUB16(dst, src);
1742 		WRITE16(ea, dst);
1743 		CYCLES(CYCLES_ALU_REG_MEM);
1744 	}
1745 }
1746 
I386OP(sbb_r16_rm16)1747 static void I386OP(sbb_r16_rm16)(void)		// Opcode 0x1b
1748 {
1749 	UINT16 src, dst;
1750 	UINT8 modrm = FETCH();
1751 	if( modrm >= 0xc0 ) {
1752 		src = LOAD_RM16(modrm) + I.CF;
1753 		dst = LOAD_REG16(modrm);
1754 		dst = SUB16(dst, src);
1755 		STORE_REG16(modrm, dst);
1756 		CYCLES(CYCLES_ALU_REG_REG);
1757 	} else {
1758 		UINT32 ea = GetEA(modrm);
1759 		src = READ16(ea) + I.CF;
1760 		dst = LOAD_REG16(modrm);
1761 		dst = SUB16(dst, src);
1762 		STORE_REG16(modrm, dst);
1763 		CYCLES(CYCLES_ALU_MEM_REG);
1764 	}
1765 }
1766 
I386OP(sbb_ax_i16)1767 static void I386OP(sbb_ax_i16)(void)		// Opcode 0x1d
1768 {
1769 	UINT16 src, dst;
1770 	src = FETCH16() + I.CF;
1771 	dst = REG16(AX);
1772 	dst = SUB16(dst, src);
1773 	REG16(AX) = dst;
1774 	CYCLES(CYCLES_ALU_IMM_ACC);
1775 }
1776 
I386OP(scasw)1777 static void I386OP(scasw)(void)				// Opcode 0xaf
1778 {
1779 	UINT32 eas;
1780 	UINT16 src, dst;
1781 	eas = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1782 	src = READ16(eas);
1783 	dst = REG16(AX);
1784 	SUB16(dst, src);
1785 	BUMP_DI(2);
1786 	CYCLES(CYCLES_SCAS);
1787 }
1788 
I386OP(shld16_i8)1789 static void I386OP(shld16_i8)(void)			// Opcode 0x0f a4
1790 {
1791 	/* TODO: Correct flags */
1792 	UINT8 modrm = FETCH();
1793 	if( modrm >= 0xc0 ) {
1794 		UINT16 dst = LOAD_RM16(modrm);
1795 		UINT16 upper = LOAD_REG16(modrm);
1796 		UINT8 shift = FETCH();
1797 		if( shift > 31 || shift == 0 ) {
1798 
1799 		} else if( shift > 15 ) {
1800 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1801 			dst = (upper << (shift-16)) | (upper >> (32-shift));
1802 			SetSZPF16(dst);
1803 		} else {
1804 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1805 			dst = (dst << shift) | (upper >> (16-shift));
1806 			SetSZPF16(dst);
1807 		}
1808 		STORE_RM16(modrm, dst);
1809 		CYCLES(CYCLES_SHLD_REG);
1810 	} else {
1811 		UINT32 ea = GetEA(modrm);
1812 		UINT16 dst = READ16(ea);
1813 		UINT16 upper = LOAD_REG16(modrm);
1814 		UINT8 shift = FETCH();
1815 		if( shift > 31 || shift == 0 ) {
1816 
1817 		} else if( shift > 15 ) {
1818 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1819 			dst = (upper << (shift-16)) | (upper >> (32-shift));
1820 			SetSZPF16(dst);
1821 		} else {
1822 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1823 			dst = (dst << shift) | (upper >> (16-shift));
1824 			SetSZPF16(dst);
1825 		}
1826 		WRITE16(ea, dst);
1827 		CYCLES(CYCLES_SHLD_MEM);
1828 	}
1829 }
1830 
I386OP(shld16_cl)1831 static void I386OP(shld16_cl)(void)			// Opcode 0x0f a5
1832 {
1833 	/* TODO: Correct flags */
1834 	UINT8 modrm = FETCH();
1835 	if( modrm >= 0xc0 ) {
1836 		UINT16 dst = LOAD_RM16(modrm);
1837 		UINT16 upper = LOAD_REG16(modrm);
1838 		UINT8 shift = REG8(CL);
1839 		if( shift > 31 || shift == 0 ) {
1840 
1841 		} else if( shift > 15 ) {
1842 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1843 			dst = (upper << (shift-16)) | (upper >> (32-shift));
1844 			SetSZPF16(dst);
1845 		} else {
1846 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1847 			dst = (dst << shift) | (upper >> (16-shift));
1848 			SetSZPF16(dst);
1849 		}
1850 		STORE_RM16(modrm, dst);
1851 		CYCLES(CYCLES_SHLD_REG);
1852 	} else {
1853 		UINT32 ea = GetEA(modrm);
1854 		UINT16 dst = READ16(ea);
1855 		UINT16 upper = LOAD_REG16(modrm);
1856 		UINT8 shift = REG8(CL);
1857 		if( shift > 31 || shift == 0 ) {
1858 
1859 		} else if( shift > 15 ) {
1860 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1861 			dst = (upper << (shift-16)) | (upper >> (32-shift));
1862 			SetSZPF16(dst);
1863 		} else {
1864 			I.CF = (dst & (1 << (16-shift))) ? 1 : 0;
1865 			dst = (dst << shift) | (upper >> (16-shift));
1866 			SetSZPF16(dst);
1867 		}
1868 		WRITE16(ea, dst);
1869 		CYCLES(CYCLES_SHLD_MEM);
1870 	}
1871 }
1872 
I386OP(shrd16_i8)1873 static void I386OP(shrd16_i8)(void)			// Opcode 0x0f ac
1874 {
1875 	/* TODO: Correct flags */
1876 	UINT8 modrm = FETCH();
1877 	if( modrm >= 0xc0 ) {
1878 		UINT16 dst = LOAD_RM16(modrm);
1879 		UINT16 upper = LOAD_REG16(modrm);
1880 		UINT8 shift = FETCH();
1881 		if( shift > 15 || shift == 0) {
1882 
1883 		} else {
1884 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1885 			dst = (dst >> shift) | (upper << (16-shift));
1886 			SetSZPF16(dst);
1887 		}
1888 		STORE_RM16(modrm, dst);
1889 		CYCLES(CYCLES_SHRD_REG);
1890 	} else {
1891 		UINT32 ea = GetEA(modrm);
1892 		UINT16 dst = READ16(ea);
1893 		UINT16 upper = LOAD_REG16(modrm);
1894 		UINT8 shift = FETCH();
1895 		if( shift > 15 || shift == 0) {
1896 
1897 		} else {
1898 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1899 			dst = (dst >> shift) | (upper << (16-shift));
1900 			SetSZPF16(dst);
1901 		}
1902 		WRITE16(ea, dst);
1903 		CYCLES(CYCLES_SHRD_MEM);
1904 	}
1905 }
1906 
I386OP(shrd16_cl)1907 static void I386OP(shrd16_cl)(void)			// Opcode 0x0f ad
1908 {
1909 	/* TODO: Correct flags */
1910 	UINT8 modrm = FETCH();
1911 	if( modrm >= 0xc0 ) {
1912 		UINT16 dst = LOAD_RM16(modrm);
1913 		UINT16 upper = LOAD_REG16(modrm);
1914 		UINT8 shift = REG8(CL);
1915 		if( shift > 15 || shift == 0) {
1916 
1917 		} else {
1918 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1919 			dst = (dst >> shift) | (upper << (16-shift));
1920 			SetSZPF16(dst);
1921 		}
1922 		STORE_RM16(modrm, dst);
1923 		CYCLES(CYCLES_SHRD_REG);
1924 	} else {
1925 		UINT32 ea = GetEA(modrm);
1926 		UINT16 dst = READ16(ea);
1927 		UINT16 upper = LOAD_REG16(modrm);
1928 		UINT8 shift = REG8(CL);
1929 		if( shift > 15 || shift == 0) {
1930 
1931 		} else {
1932 			I.CF = (dst & (1 << (shift-1))) ? 1 : 0;
1933 			dst = (dst >> shift) | (upper << (16-shift));
1934 			SetSZPF16(dst);
1935 		}
1936 		WRITE16(ea, dst);
1937 		CYCLES(CYCLES_SHRD_MEM);
1938 	}
1939 }
1940 
I386OP(stosw)1941 static void I386OP(stosw)(void)				// Opcode 0xab
1942 {
1943 	UINT32 ead;
1944 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1945 	WRITE16(ead, REG16(AX));
1946 	BUMP_DI(2);
1947 	CYCLES(CYCLES_STOS);
1948 }
1949 
I386OP(sub_rm16_r16)1950 static void I386OP(sub_rm16_r16)(void)		// Opcode 0x29
1951 {
1952 	UINT16 src, dst;
1953 	UINT8 modrm = FETCH();
1954 	if( modrm >= 0xc0 ) {
1955 		src = LOAD_REG16(modrm);
1956 		dst = LOAD_RM16(modrm);
1957 		dst = SUB16(dst, src);
1958 		STORE_RM16(modrm, dst);
1959 		CYCLES(CYCLES_ALU_REG_REG);
1960 	} else {
1961 		UINT32 ea = GetEA(modrm);
1962 		src = LOAD_REG16(modrm);
1963 		dst = READ16(ea);
1964 		dst = SUB16(dst, src);
1965 		WRITE16(ea, dst);
1966 		CYCLES(CYCLES_ALU_REG_MEM);
1967 	}
1968 }
1969 
I386OP(sub_r16_rm16)1970 static void I386OP(sub_r16_rm16)(void)		// Opcode 0x2b
1971 {
1972 	UINT16 src, dst;
1973 	UINT8 modrm = FETCH();
1974 	if( modrm >= 0xc0 ) {
1975 		src = LOAD_RM16(modrm);
1976 		dst = LOAD_REG16(modrm);
1977 		dst = SUB16(dst, src);
1978 		STORE_REG16(modrm, dst);
1979 		CYCLES(CYCLES_ALU_REG_REG);
1980 	} else {
1981 		UINT32 ea = GetEA(modrm);
1982 		src = READ16(ea);
1983 		dst = LOAD_REG16(modrm);
1984 		dst = SUB16(dst, src);
1985 		STORE_REG16(modrm, dst);
1986 		CYCLES(CYCLES_ALU_MEM_REG);
1987 	}
1988 }
1989 
I386OP(sub_ax_i16)1990 static void I386OP(sub_ax_i16)(void)		// Opcode 0x2d
1991 {
1992 	UINT16 src, dst;
1993 	src = FETCH16();
1994 	dst = REG16(AX);
1995 	dst = SUB16(dst, src);
1996 	REG16(AX) = dst;
1997 	CYCLES(CYCLES_ALU_IMM_ACC);
1998 }
1999 
I386OP(test_ax_i16)2000 static void I386OP(test_ax_i16)(void)		// Opcode 0xa9
2001 {
2002 	UINT16 src = FETCH16();
2003 	UINT16 dst = REG16(AX);
2004 	dst = src & dst;
2005 	SetSZPF16(dst);
2006 	I.CF = 0;
2007 	I.OF = 0;
2008 	CYCLES(CYCLES_TEST_IMM_ACC);
2009 }
2010 
I386OP(test_rm16_r16)2011 static void I386OP(test_rm16_r16)(void)		// Opcode 0x85
2012 {
2013 	UINT16 src, dst;
2014 	UINT8 modrm = FETCH();
2015 	if( modrm >= 0xc0 ) {
2016 		src = LOAD_REG16(modrm);
2017 		dst = LOAD_RM16(modrm);
2018 		dst = src & dst;
2019 		SetSZPF16(dst);
2020 		I.CF = 0;
2021 		I.OF = 0;
2022 		CYCLES(CYCLES_TEST_REG_REG);
2023 	} else {
2024 		UINT32 ea = GetEA(modrm);
2025 		src = LOAD_REG16(modrm);
2026 		dst = READ16(ea);
2027 		dst = src & dst;
2028 		SetSZPF16(dst);
2029 		I.CF = 0;
2030 		I.OF = 0;
2031 		CYCLES(CYCLES_TEST_REG_MEM);
2032 	}
2033 }
2034 
I386OP(xchg_ax_cx)2035 static void I386OP(xchg_ax_cx)(void)		// Opcode 0x91
2036 {
2037 	UINT16 temp;
2038 	temp = REG16(AX);
2039 	REG16(AX) = REG16(CX);
2040 	REG16(CX) = temp;
2041 	CYCLES(CYCLES_XCHG_REG_REG);
2042 }
2043 
I386OP(xchg_ax_dx)2044 static void I386OP(xchg_ax_dx)(void)		// Opcode 0x92
2045 {
2046 	UINT16 temp;
2047 	temp = REG16(AX);
2048 	REG16(AX) = REG16(DX);
2049 	REG16(DX) = temp;
2050 	CYCLES(CYCLES_XCHG_REG_REG);
2051 }
2052 
I386OP(xchg_ax_bx)2053 static void I386OP(xchg_ax_bx)(void)		// Opcode 0x93
2054 {
2055 	UINT16 temp;
2056 	temp = REG16(AX);
2057 	REG16(AX) = REG16(BX);
2058 	REG16(BX) = temp;
2059 	CYCLES(CYCLES_XCHG_REG_REG);
2060 }
2061 
I386OP(xchg_ax_sp)2062 static void I386OP(xchg_ax_sp)(void)		// Opcode 0x94
2063 {
2064 	UINT16 temp;
2065 	temp = REG16(AX);
2066 	REG16(AX) = REG16(SP);
2067 	REG16(SP) = temp;
2068 	CYCLES(CYCLES_XCHG_REG_REG);
2069 }
2070 
I386OP(xchg_ax_bp)2071 static void I386OP(xchg_ax_bp)(void)		// Opcode 0x95
2072 {
2073 	UINT16 temp;
2074 	temp = REG16(AX);
2075 	REG16(AX) = REG16(BP);
2076 	REG16(BP) = temp;
2077 	CYCLES(CYCLES_XCHG_REG_REG);
2078 }
2079 
I386OP(xchg_ax_si)2080 static void I386OP(xchg_ax_si)(void)		// Opcode 0x96
2081 {
2082 	UINT16 temp;
2083 	temp = REG16(AX);
2084 	REG16(AX) = REG16(SI);
2085 	REG16(SI) = temp;
2086 	CYCLES(CYCLES_XCHG_REG_REG);
2087 }
2088 
I386OP(xchg_ax_di)2089 static void I386OP(xchg_ax_di)(void)		// Opcode 0x97
2090 {
2091 	UINT16 temp;
2092 	temp = REG16(AX);
2093 	REG16(AX) = REG16(DI);
2094 	REG16(DI) = temp;
2095 	CYCLES(CYCLES_XCHG_REG_REG);
2096 }
2097 
I386OP(xchg_r16_rm16)2098 static void I386OP(xchg_r16_rm16)(void)		// Opcode 0x87
2099 {
2100 	UINT8 modrm = FETCH();
2101 	if( modrm >= 0xc0 ) {
2102 		UINT16 src = LOAD_RM16(modrm);
2103 		UINT16 dst = LOAD_REG16(modrm);
2104 		STORE_REG16(modrm, src);
2105 		STORE_RM16(modrm, dst);
2106 		CYCLES(CYCLES_XCHG_REG_REG);
2107 	} else {
2108 		UINT32 ea = GetEA(modrm);
2109 		UINT16 src = READ16(ea);
2110 		UINT16 dst = LOAD_REG16(modrm);
2111 		STORE_REG16(modrm, src);
2112 		WRITE16(ea, dst);
2113 		CYCLES(CYCLES_XCHG_REG_MEM);
2114 	}
2115 }
2116 
I386OP(xor_rm16_r16)2117 static void I386OP(xor_rm16_r16)(void)		// Opcode 0x31
2118 {
2119 	UINT16 src, dst;
2120 	UINT8 modrm = FETCH();
2121 	if( modrm >= 0xc0 ) {
2122 		src = LOAD_REG16(modrm);
2123 		dst = LOAD_RM16(modrm);
2124 		dst = XOR16(dst, src);
2125 		STORE_RM16(modrm, dst);
2126 		CYCLES(CYCLES_ALU_REG_REG);
2127 	} else {
2128 		UINT32 ea = GetEA(modrm);
2129 		src = LOAD_REG16(modrm);
2130 		dst = READ16(ea);
2131 		dst = XOR16(dst, src);
2132 		WRITE16(ea, dst);
2133 		CYCLES(CYCLES_ALU_REG_MEM);
2134 	}
2135 }
2136 
I386OP(xor_r16_rm16)2137 static void I386OP(xor_r16_rm16)(void)		// Opcode 0x33
2138 {
2139 	UINT16 src, dst;
2140 	UINT8 modrm = FETCH();
2141 	if( modrm >= 0xc0 ) {
2142 		src = LOAD_RM16(modrm);
2143 		dst = LOAD_REG16(modrm);
2144 		dst = XOR16(dst, src);
2145 		STORE_REG16(modrm, dst);
2146 		CYCLES(CYCLES_ALU_REG_REG);
2147 	} else {
2148 		UINT32 ea = GetEA(modrm);
2149 		src = READ16(ea);
2150 		dst = LOAD_REG16(modrm);
2151 		dst = XOR16(dst, src);
2152 		STORE_REG16(modrm, dst);
2153 		CYCLES(CYCLES_ALU_MEM_REG);
2154 	}
2155 }
2156 
I386OP(xor_ax_i16)2157 static void I386OP(xor_ax_i16)(void)		// Opcode 0x35
2158 {
2159 	UINT16 src, dst;
2160 	src = FETCH16();
2161 	dst = REG16(AX);
2162 	dst = XOR16(dst, src);
2163 	REG16(AX) = dst;
2164 	CYCLES(CYCLES_ALU_IMM_ACC);
2165 }
2166 
2167 
2168 
I386OP(group81_16)2169 static void I386OP(group81_16)(void)		// Opcode 0x81
2170 {
2171 	UINT32 ea;
2172 	UINT16 src, dst;
2173 	UINT8 modrm = FETCH();
2174 
2175 	switch( (modrm >> 3) & 0x7 )
2176 	{
2177 		case 0:		// ADD Rm16, i16
2178 			if( modrm >= 0xc0 ) {
2179 				dst = LOAD_RM16(modrm);
2180 				src = FETCH16();
2181 				dst = ADD16(dst, src);
2182 				STORE_RM16(modrm, dst);
2183 				CYCLES(CYCLES_ALU_REG_REG);
2184 			} else {
2185 				ea = GetEA(modrm);
2186 				dst = READ16(ea);
2187 				src = FETCH16();
2188 				dst = ADD16(dst, src);
2189 				WRITE16(ea, dst);
2190 				CYCLES(CYCLES_ALU_REG_MEM);
2191 			}
2192 			break;
2193 		case 1:		// OR Rm16, i16
2194 			if( modrm >= 0xc0 ) {
2195 				dst = LOAD_RM16(modrm);
2196 				src = FETCH16();
2197 				dst = OR16(dst, src);
2198 				STORE_RM16(modrm, dst);
2199 				CYCLES(CYCLES_ALU_REG_REG);
2200 			} else {
2201 				ea = GetEA(modrm);
2202 				dst = READ16(ea);
2203 				src = FETCH16();
2204 				dst = OR16(dst, src);
2205 				WRITE16(ea, dst);
2206 				CYCLES(CYCLES_ALU_REG_MEM);
2207 			}
2208 			break;
2209 		case 2:		// ADC Rm16, i16
2210 			if( modrm >= 0xc0 ) {
2211 				dst = LOAD_RM16(modrm);
2212 				src = FETCH16();
2213 				src = ADD16(src, I.CF);
2214 				dst = ADD16(dst, src);
2215 				STORE_RM16(modrm, dst);
2216 				CYCLES(CYCLES_ALU_REG_REG);
2217 			} else {
2218 				ea = GetEA(modrm);
2219 				dst = READ16(ea);
2220 				src = FETCH16();
2221 				src = ADD16(src, I.CF);
2222 				dst = ADD16(dst, src);
2223 				WRITE16(ea, dst);
2224 				CYCLES(CYCLES_ALU_REG_MEM);
2225 			}
2226 			break;
2227 		case 3:		// SBB Rm16, i16
2228 			if( modrm >= 0xc0 ) {
2229 				dst = LOAD_RM16(modrm);
2230 				src = FETCH16() + I.CF;
2231 				dst = SUB16(dst, src);
2232 				STORE_RM16(modrm, dst);
2233 				CYCLES(CYCLES_ALU_REG_REG);
2234 			} else {
2235 				ea = GetEA(modrm);
2236 				dst = READ16(ea);
2237 				src = FETCH16() + I.CF;
2238 				dst = SUB16(dst, src);
2239 				WRITE16(ea, dst);
2240 				CYCLES(CYCLES_ALU_REG_MEM);
2241 			}
2242 			break;
2243 		case 4:		// AND Rm16, i16
2244 			if( modrm >= 0xc0 ) {
2245 				dst = LOAD_RM16(modrm);
2246 				src = FETCH16();
2247 				dst = AND16(dst, src);
2248 				STORE_RM16(modrm, dst);
2249 				CYCLES(CYCLES_ALU_REG_REG);
2250 			} else {
2251 				ea = GetEA(modrm);
2252 				dst = READ16(ea);
2253 				src = FETCH16();
2254 				dst = AND16(dst, src);
2255 				WRITE16(ea, dst);
2256 				CYCLES(CYCLES_ALU_REG_MEM);
2257 			}
2258 			break;
2259 		case 5:		// SUB Rm16, i16
2260 			if( modrm >= 0xc0 ) {
2261 				dst = LOAD_RM16(modrm);
2262 				src = FETCH16();
2263 				dst = SUB16(dst, src);
2264 				STORE_RM16(modrm, dst);
2265 				CYCLES(CYCLES_ALU_REG_REG);
2266 			} else {
2267 				ea = GetEA(modrm);
2268 				dst = READ16(ea);
2269 				src = FETCH16();
2270 				dst = SUB16(dst, src);
2271 				WRITE16(ea, dst);
2272 				CYCLES(CYCLES_ALU_REG_MEM);
2273 			}
2274 			break;
2275 		case 6:		// XOR Rm16, i16
2276 			if( modrm >= 0xc0 ) {
2277 				dst = LOAD_RM16(modrm);
2278 				src = FETCH16();
2279 				dst = XOR16(dst, src);
2280 				STORE_RM16(modrm, dst);
2281 				CYCLES(CYCLES_ALU_REG_REG);
2282 			} else {
2283 				ea = GetEA(modrm);
2284 				dst = READ16(ea);
2285 				src = FETCH16();
2286 				dst = XOR16(dst, src);
2287 				WRITE16(ea, dst);
2288 				CYCLES(CYCLES_ALU_REG_MEM);
2289 			}
2290 			break;
2291 		case 7:		// CMP Rm16, i16
2292 			if( modrm >= 0xc0 ) {
2293 				dst = LOAD_RM16(modrm);
2294 				src = FETCH16();
2295 				SUB16(dst, src);
2296 				CYCLES(CYCLES_CMP_REG_REG);
2297 			} else {
2298 				ea = GetEA(modrm);
2299 				dst = READ16(ea);
2300 				src = FETCH16();
2301 				SUB16(dst, src);
2302 				CYCLES(CYCLES_CMP_REG_MEM);
2303 			}
2304 			break;
2305 	}
2306 }
2307 
I386OP(group83_16)2308 static void I386OP(group83_16)(void)		// Opcode 0x83
2309 {
2310 	UINT32 ea;
2311 	UINT16 src, dst;
2312 	UINT8 modrm = FETCH();
2313 
2314 	switch( (modrm >> 3) & 0x7 )
2315 	{
2316 		case 0:		// ADD Rm16, i16
2317 			if( modrm >= 0xc0 ) {
2318 				dst = LOAD_RM16(modrm);
2319 				src = (UINT16)(INT16)(INT8)FETCH();
2320 				dst = ADD16(dst, src);
2321 				STORE_RM16(modrm, dst);
2322 				CYCLES(CYCLES_ALU_REG_REG);
2323 			} else {
2324 				ea = GetEA(modrm);
2325 				dst = READ16(ea);
2326 				src = (UINT16)(INT16)(INT8)FETCH();
2327 				dst = ADD16(dst, src);
2328 				WRITE16(ea, dst);
2329 				CYCLES(CYCLES_ALU_REG_MEM);
2330 			}
2331 			break;
2332 		case 1:		// OR Rm16, i16
2333 			if( modrm >= 0xc0 ) {
2334 				dst = LOAD_RM16(modrm);
2335 				src = (UINT16)(INT16)(INT8)FETCH();
2336 				dst = OR16(dst, src);
2337 				STORE_RM16(modrm, dst);
2338 				CYCLES(CYCLES_ALU_REG_REG);
2339 			} else {
2340 				ea = GetEA(modrm);
2341 				dst = READ16(ea);
2342 				src = (UINT16)(INT16)(INT8)FETCH();
2343 				dst = OR16(dst, src);
2344 				WRITE16(ea, dst);
2345 				CYCLES(CYCLES_ALU_REG_MEM);
2346 			}
2347 			break;
2348 		case 2:		// ADC Rm16, i16
2349 			if( modrm >= 0xc0 ) {
2350 				dst = LOAD_RM16(modrm);
2351 				src = (UINT16)(INT16)(INT8)FETCH();
2352 				src = ADD16(src, I.CF);
2353 				dst = ADD16(dst, src);
2354 				STORE_RM16(modrm, dst);
2355 				CYCLES(CYCLES_ALU_REG_REG);
2356 			} else {
2357 				ea = GetEA(modrm);
2358 				dst = READ16(ea);
2359 				src = (UINT16)(INT16)(INT8)FETCH();
2360 				src = ADD16(src, I.CF);
2361 				dst = ADD16(dst, src);
2362 				WRITE16(ea, dst);
2363 				CYCLES(CYCLES_ALU_REG_MEM);
2364 			}
2365 			break;
2366 		case 3:		// SBB Rm16, i16
2367 			if( modrm >= 0xc0 ) {
2368 				dst = LOAD_RM16(modrm);
2369 				src = ((UINT16)(INT16)(INT8)FETCH()) + I.CF;
2370 				dst = SUB16(dst, src);
2371 				STORE_RM16(modrm, dst);
2372 				CYCLES(CYCLES_ALU_REG_REG);
2373 			} else {
2374 				ea = GetEA(modrm);
2375 				dst = READ16(ea);
2376 				src = ((UINT16)(INT16)(INT8)FETCH()) + I.CF;
2377 				dst = SUB16(dst, src);
2378 				WRITE16(ea, dst);
2379 				CYCLES(CYCLES_ALU_REG_MEM);
2380 			}
2381 			break;
2382 		case 4:		// AND Rm16, i16
2383 			if( modrm >= 0xc0 ) {
2384 				dst = LOAD_RM16(modrm);
2385 				src = (UINT16)(INT16)(INT8)FETCH();
2386 				dst = AND16(dst, src);
2387 				STORE_RM16(modrm, dst);
2388 				CYCLES(CYCLES_ALU_REG_REG);
2389 			} else {
2390 				ea = GetEA(modrm);
2391 				dst = READ16(ea);
2392 				src = (UINT16)(INT16)(INT8)FETCH();
2393 				dst = AND16(dst, src);
2394 				WRITE16(ea, dst);
2395 				CYCLES(CYCLES_ALU_REG_MEM);
2396 			}
2397 			break;
2398 		case 5:		// SUB Rm16, i16
2399 			if( modrm >= 0xc0 ) {
2400 				dst = LOAD_RM16(modrm);
2401 				src = (UINT16)(INT16)(INT8)FETCH();
2402 				dst = SUB16(dst, src);
2403 				STORE_RM16(modrm, dst);
2404 				CYCLES(CYCLES_ALU_REG_REG);
2405 			} else {
2406 				ea = GetEA(modrm);
2407 				dst = READ16(ea);
2408 				src = (UINT16)(INT16)(INT8)FETCH();
2409 				dst = SUB16(dst, src);
2410 				WRITE16(ea, dst);
2411 				CYCLES(CYCLES_ALU_REG_MEM);
2412 			}
2413 			break;
2414 		case 6:		// XOR Rm16, i16
2415 			if( modrm >= 0xc0 ) {
2416 				dst = LOAD_RM16(modrm);
2417 				src = (UINT16)(INT16)(INT8)FETCH();
2418 				dst = XOR16(dst, src);
2419 				STORE_RM16(modrm, dst);
2420 				CYCLES(CYCLES_ALU_REG_REG);
2421 			} else {
2422 				ea = GetEA(modrm);
2423 				dst = READ16(ea);
2424 				src = (UINT16)(INT16)(INT8)FETCH();
2425 				dst = XOR16(dst, src);
2426 				WRITE16(ea, dst);
2427 				CYCLES(CYCLES_ALU_REG_MEM);
2428 			}
2429 			break;
2430 		case 7:		// CMP Rm16, i16
2431 			if( modrm >= 0xc0 ) {
2432 				dst = LOAD_RM16(modrm);
2433 				src = (UINT16)(INT16)(INT8)FETCH();
2434 				SUB16(dst, src);
2435 				CYCLES(CYCLES_CMP_REG_REG);
2436 			} else {
2437 				ea = GetEA(modrm);
2438 				dst = READ16(ea);
2439 				src = (UINT16)(INT16)(INT8)FETCH();
2440 				SUB16(dst, src);
2441 				CYCLES(CYCLES_CMP_REG_MEM);
2442 			}
2443 			break;
2444 	}
2445 }
2446 
I386OP(groupC1_16)2447 static void I386OP(groupC1_16)(void)		// Opcode 0xc1
2448 {
2449 	UINT16 dst;
2450 	UINT8 modrm = FETCH();
2451 	UINT8 shift;
2452 
2453 	if( modrm >= 0xc0 ) {
2454 		dst = LOAD_RM16(modrm);
2455 		shift = FETCH() & 0x1f;
2456 		dst = i386_shift_rotate16(modrm, dst, shift);
2457 		STORE_RM16(modrm, dst);
2458 	} else {
2459 		UINT32 ea = GetEA(modrm);
2460 		dst = READ16(ea);
2461 		shift = FETCH() & 0x1f;
2462 		dst = i386_shift_rotate16(modrm, dst, shift);
2463 		WRITE16(ea, dst);
2464 	}
2465 }
2466 
I386OP(groupD1_16)2467 static void I386OP(groupD1_16)(void)		// Opcode 0xd1
2468 {
2469 	UINT16 dst;
2470 	UINT8 modrm = FETCH();
2471 
2472 	if( modrm >= 0xc0 ) {
2473 		dst = LOAD_RM16(modrm);
2474 		dst = i386_shift_rotate16(modrm, dst, 1);
2475 		STORE_RM16(modrm, dst);
2476 	} else {
2477 		UINT32 ea = GetEA(modrm);
2478 		dst = READ16(ea);
2479 		dst = i386_shift_rotate16(modrm, dst, 1);
2480 		WRITE16(ea, dst);
2481 	}
2482 }
2483 
I386OP(groupD3_16)2484 static void I386OP(groupD3_16)(void)		// Opcode 0xd3
2485 {
2486 	UINT16 dst;
2487 	UINT8 modrm = FETCH();
2488 
2489 	if( modrm >= 0xc0 ) {
2490 		dst = LOAD_RM16(modrm);
2491 		dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2492 		STORE_RM16(modrm, dst);
2493 	} else {
2494 		UINT32 ea = GetEA(modrm);
2495 		dst = READ16(ea);
2496 		dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2497 		WRITE16(ea, dst);
2498 	}
2499 }
2500 
I386OP(groupF7_16)2501 static void I386OP(groupF7_16)(void)		// Opcode 0xf7
2502 {
2503 	UINT8 modrm = FETCH();
2504 
2505 	switch( (modrm >> 3) & 0x7 )
2506 	{
2507 		case 0:			/* TEST Rm16, i16 */
2508 			if( modrm >= 0xc0 ) {
2509 				UINT16 dst = LOAD_RM16(modrm);
2510 				UINT16 src = FETCH16();
2511 				dst &= src;
2512 				I.CF = I.OF = I.AF = 0;
2513 				SetSZPF16(dst);
2514 				CYCLES(CYCLES_TEST_IMM_REG);
2515 			} else {
2516 				UINT32 ea = GetEA(modrm);
2517 				UINT16 dst = READ16(ea);
2518 				UINT16 src = FETCH16();
2519 				dst &= src;
2520 				I.CF = I.OF = I.AF = 0;
2521 				SetSZPF16(dst);
2522 				CYCLES(CYCLES_TEST_IMM_MEM);
2523 			}
2524 			break;
2525 		case 2:			/* NOT Rm16 */
2526 			if( modrm >= 0xc0 ) {
2527 				UINT16 dst = LOAD_RM16(modrm);
2528 				dst = ~dst;
2529 				STORE_RM16(modrm, dst);
2530 				CYCLES(CYCLES_NOT_REG);
2531 			} else {
2532 				UINT32 ea = GetEA(modrm);
2533 				UINT16 dst = READ16(ea);
2534 				dst = ~dst;
2535 				WRITE16(ea, dst);
2536 				CYCLES(CYCLES_NOT_MEM);
2537 			}
2538 			break;
2539 		case 3:			/* NEG Rm16 */
2540 			if( modrm >= 0xc0 ) {
2541 				UINT16 dst = LOAD_RM16(modrm);
2542 				dst = SUB16( 0, dst );
2543 				STORE_RM16(modrm, dst);
2544 				CYCLES(CYCLES_NEG_REG);
2545 			} else {
2546 				UINT32 ea = GetEA(modrm);
2547 				UINT16 dst = READ16(ea);
2548 				dst = SUB16( 0, dst );
2549 				WRITE16(ea, dst);
2550 				CYCLES(CYCLES_NEG_MEM);
2551 			}
2552 			break;
2553 		case 4:			/* MUL AX, Rm16 */
2554 			{
2555 				UINT32 result;
2556 				UINT16 src, dst;
2557 				if( modrm >= 0xc0 ) {
2558 					src = LOAD_RM16(modrm);
2559 					CYCLES(CYCLES_MUL16_ACC_REG);		/* TODO: Correct multiply timing */
2560 				} else {
2561 					UINT32 ea = GetEA(modrm);
2562 					src = READ16(ea);
2563 					CYCLES(CYCLES_MUL16_ACC_MEM);		/* TODO: Correct multiply timing */
2564 				}
2565 
2566 				dst = REG16(AX);
2567 				result = (UINT32)src * (UINT32)dst;
2568 				REG16(DX) = (UINT16)(result >> 16);
2569 				REG16(AX) = (UINT16)result;
2570 
2571 				I.CF = I.OF = (REG16(DX) != 0);
2572 			}
2573 			break;
2574 		case 5:			/* IMUL AX, Rm16 */
2575 			{
2576 				INT32 result;
2577 				INT32 src, dst;
2578 				if( modrm >= 0xc0 ) {
2579 					src = (INT32)(INT16)LOAD_RM16(modrm);
2580 					CYCLES(CYCLES_IMUL16_ACC_REG);		/* TODO: Correct multiply timing */
2581 				} else {
2582 					UINT32 ea = GetEA(modrm);
2583 					src = (INT32)(INT16)READ16(ea);
2584 					CYCLES(CYCLES_IMUL16_ACC_MEM);		/* TODO: Correct multiply timing */
2585 				}
2586 
2587 				dst = (INT32)(INT16)REG16(AX);
2588 				result = src * dst;
2589 
2590 				REG16(DX) = (UINT16)(result >> 16);
2591 				REG16(AX) = (UINT16)result;
2592 
2593 				I.CF = I.OF = !(result == (INT32)(INT16)result);
2594 			}
2595 			break;
2596 		case 6:			/* DIV AX, Rm16 */
2597 			{
2598 				UINT32 quotient, remainder, result;
2599 				UINT16 src;
2600 				if( modrm >= 0xc0 ) {
2601 					src = LOAD_RM16(modrm);
2602 					CYCLES(CYCLES_DIV16_ACC_REG);
2603 				} else {
2604 					UINT32 ea = GetEA(modrm);
2605 					src = READ16(ea);
2606 					CYCLES(CYCLES_DIV16_ACC_MEM);
2607 				}
2608 
2609 				quotient = ((UINT32)(REG16(DX)) << 16) | (UINT32)(REG16(AX));
2610 				if( src ) {
2611 					remainder = quotient % (UINT32)src;
2612 					result = quotient / (UINT32)src;
2613 					if( result > 0xffff ) {
2614 						/* TODO: Divide error */
2615 					} else {
2616 						REG16(DX) = (UINT16)remainder;
2617 						REG16(AX) = (UINT16)result;
2618 					}
2619 				} else {
2620 					/* TODO: Divide by zero */
2621 				}
2622 			}
2623 			break;
2624 		case 7:			/* IDIV AX, Rm16 */
2625 			{
2626 				INT32 quotient, remainder, result;
2627 				UINT16 src;
2628 				if( modrm >= 0xc0 ) {
2629 					src = LOAD_RM16(modrm);
2630 					CYCLES(CYCLES_IDIV16_ACC_REG);
2631 				} else {
2632 					UINT32 ea = GetEA(modrm);
2633 					src = READ16(ea);
2634 					CYCLES(CYCLES_IDIV16_ACC_MEM);
2635 				}
2636 
2637 				quotient = (((INT32)REG16(DX)) << 16) | ((UINT32)REG16(AX));
2638 				if( src ) {
2639 					remainder = quotient % (INT32)(INT16)src;
2640 					result = quotient / (INT32)(INT16)src;
2641 					if( result > 0xffff ) {
2642 						/* TODO: Divide error */
2643 					} else {
2644 						REG16(DX) = (UINT16)remainder;
2645 						REG16(AX) = (UINT16)result;
2646 					}
2647 				} else {
2648 					/* TODO: Divide by zero */
2649 				}
2650 			}
2651 			break;
2652 	}
2653 }
2654 
I386OP(groupFF_16)2655 static void I386OP(groupFF_16)(void)		// Opcode 0xff
2656 {
2657 	UINT8 modrm = FETCH();
2658 
2659 	switch( (modrm >> 3) & 0x7 )
2660 	{
2661 		case 0:			/* INC Rm16 */
2662 			if( modrm >= 0xc0 ) {
2663 				UINT16 dst = LOAD_RM16(modrm);
2664 				dst = INC16(dst);
2665 				STORE_RM16(modrm, dst);
2666 				CYCLES(CYCLES_INC_REG);
2667 			} else {
2668 				UINT32 ea = GetEA(modrm);
2669 				UINT16 dst = READ16(ea);
2670 				dst = INC16(dst);
2671 				WRITE16(ea, dst);
2672 				CYCLES(CYCLES_INC_MEM);
2673 			}
2674 			break;
2675 		case 1:			/* DEC Rm16 */
2676 			if( modrm >= 0xc0 ) {
2677 				UINT16 dst = LOAD_RM16(modrm);
2678 				dst = DEC16(dst);
2679 				STORE_RM16(modrm, dst);
2680 				CYCLES(CYCLES_DEC_REG);
2681 			} else {
2682 				UINT32 ea = GetEA(modrm);
2683 				UINT16 dst = READ16(ea);
2684 				dst = DEC16(dst);
2685 				WRITE16(ea, dst);
2686 				CYCLES(CYCLES_DEC_MEM);
2687 			}
2688 			break;
2689 		case 2:			/* CALL Rm16 */
2690 			{
2691 				UINT16 address = 0;
2692 				if( modrm >= 0xc0 ) {
2693 					address = LOAD_RM16(modrm);
2694 					CYCLES(CYCLES_CALL_REG);		/* TODO: Timing = 7 + m */
2695 				} else {
2696 					UINT32 ea = GetEA(modrm);
2697 					address = READ16(ea);
2698 					CYCLES(CYCLES_CALL_MEM);		/* TODO: Timing = 10 + m */
2699 				}
2700 				PUSH16( I.eip );
2701 				I.eip = address;
2702 				CHANGE_PC(I.eip);
2703 			}
2704 			break;
2705 		case 3:			/* CALL FAR Rm16 */
2706 			{
2707 				UINT16 address = 0, selector = 0;
2708 				if( modrm >= 0xc0 ) {
2709 				//	osd_die("NYI");
2710 				} else {
2711 					UINT32 ea = GetEA(modrm);
2712 					address = READ16(ea + 0);
2713 					selector = READ16(ea + 2);
2714 					CYCLES(CYCLES_CALL_MEM_INTERSEG);		/* TODO: Timing = 10 + m */
2715 				}
2716 				PUSH16( I.sreg[CS].selector );
2717 				PUSH16( I.eip );
2718 				I.sreg[CS].selector = selector;
2719 				I.performed_intersegment_jump = 1;
2720 				i386_load_segment_descriptor( CS );
2721 				I.eip = address;
2722 				CHANGE_PC(I.eip);
2723 			}
2724 			break;
2725 		case 4:			/* JMP Rm16 */
2726 			{
2727 				UINT16 address;
2728 				if( modrm >= 0xc0 ) {
2729 					address = LOAD_RM16(modrm);
2730 					CYCLES(CYCLES_JMP_REG);		/* TODO: Timing = 7 + m */
2731 				} else {
2732 					UINT32 ea = GetEA(modrm);
2733 					address = READ16(ea);
2734 					CYCLES(CYCLES_JMP_MEM);		/* TODO: Timing = 10 + m */
2735 				}
2736 				I.eip = address;
2737 				CHANGE_PC(I.eip);
2738 			}
2739 			break;
2740 		case 5:			/* JMP FAR Rm16 */
2741 			{
2742 				UINT16 address = 0, selector = 0;
2743 				if( modrm >= 0xc0 ) {
2744 				//	osd_die("NYI");
2745 				} else {
2746 					UINT32 ea = GetEA(modrm);
2747 					address = READ16(ea + 0);
2748 					selector = READ16(ea + 2);
2749 					CYCLES(CYCLES_JMP_MEM_INTERSEG);		/* TODO: Timing = 10 + m */
2750 				}
2751 				I.sreg[CS].selector = selector;
2752 				I.performed_intersegment_jump = 1;
2753 				i386_load_segment_descriptor( CS );
2754 				I.eip = address;
2755 				CHANGE_PC(I.eip);
2756 			}
2757 			break;
2758 		case 6:			/* PUSH Rm16 */
2759 			{
2760 				UINT16 value;
2761 				if( modrm >= 0xc0 ) {
2762 					value = LOAD_RM16(modrm);
2763 				} else {
2764 					UINT32 ea = GetEA(modrm);
2765 					value = READ16(ea);
2766 				}
2767 				PUSH16(value);
2768 				CYCLES(CYCLES_PUSH_RM);
2769 			}
2770 			break;
2771 		case 7:
2772 			I386OP(invalid)();
2773 			break;
2774 		default:
2775 		//	osd_die("i386: groupFF_16 /%d unimplemented\n", (modrm >> 3) & 0x7);
2776 			break;
2777 	}
2778 }
2779 
I386OP(group0F00_16)2780 static void I386OP(group0F00_16)(void)			// Opcode 0x0f 00
2781 {
2782 	UINT32 address, ea;
2783 	UINT8 modrm = FETCH();
2784 
2785 	switch( (modrm >> 3) & 0x7 )
2786 	{
2787 		case 2:			/* LLDT */
2788 			if ( PROTECTED_MODE && !V8086_MODE )
2789 			{
2790 				if( modrm >= 0xc0 ) {
2791 					address = LOAD_RM16(modrm);
2792 					ea = i386_translate( CS, address );
2793 					CYCLES(CYCLES_LLDT_REG);
2794 				} else {
2795 					ea = GetEA(modrm);
2796 					CYCLES(CYCLES_LLDT_MEM);
2797 				}
2798 				I.ldtr.segment = READ16(ea);
2799 			}
2800 			else
2801 			{
2802 				i386_trap(6, 0);
2803 			}
2804 			break;
2805 
2806 		case 3:			/* LTR */
2807 			if ( PROTECTED_MODE && !V8086_MODE )
2808 			{
2809 				if( modrm >= 0xc0 ) {
2810 					address = LOAD_RM16(modrm);
2811 					ea = i386_translate( CS, address );
2812 					CYCLES(CYCLES_LTR_REG);
2813 				} else {
2814 					ea = GetEA(modrm);
2815 					CYCLES(CYCLES_LTR_MEM);
2816 				}
2817 				I.task.segment = READ16(ea);
2818 			}
2819 			else
2820 			{
2821 				i386_trap(6, 0);
2822 			}
2823 			break;
2824 
2825 		default:
2826 		//	osd_die("i386: group0F00_16 /%d unimplemented\n", (modrm >> 3) & 0x7);
2827 			break;
2828 	}
2829 }
2830 
I386OP(group0F01_16)2831 static void I386OP(group0F01_16)(void)		// Opcode 0x0f 01
2832 {
2833 	UINT8 modrm = FETCH();
2834 	UINT16 address;
2835 	UINT32 ea;
2836 
2837 	switch( (modrm >> 3) & 0x7 )
2838 	{
2839 		case 0:			/* SGDT */
2840 			{
2841 				if( modrm >= 0xc0 ) {
2842 					address = LOAD_RM16(modrm);
2843 					ea = i386_translate( CS, address );
2844 				} else {
2845 					ea = GetEA(modrm);
2846 				}
2847 				WRITE16(ea, I.gdtr.limit);
2848 				WRITE32(ea + 2, I.gdtr.base & 0xffffff);
2849 				CYCLES(CYCLES_SGDT);
2850 				break;
2851 			}
2852 		case 1:			/* SIDT */
2853 			{
2854 				if (modrm >= 0xc0)
2855 				{
2856 					address = LOAD_RM16(modrm);
2857 					ea = i386_translate( CS, address );
2858 				}
2859 				else
2860 				{
2861 					ea = GetEA(modrm);
2862 				}
2863 				WRITE16(ea, I.idtr.limit);
2864 				WRITE32(ea + 2, I.idtr.base & 0xffffff);
2865 				CYCLES(CYCLES_SIDT);
2866 				break;
2867 			}
2868 		case 2:			/* LGDT */
2869 			{
2870 				if( modrm >= 0xc0 ) {
2871 					address = LOAD_RM16(modrm);
2872 					ea = i386_translate( CS, address );
2873 				} else {
2874 					ea = GetEA(modrm);
2875 				}
2876 				I.gdtr.limit = READ16(ea);
2877 				I.gdtr.base = READ32(ea + 2) & 0xffffff;
2878 				CYCLES(CYCLES_LGDT);
2879 				break;
2880 			}
2881 		case 3:			/* LIDT */
2882 			{
2883 				if( modrm >= 0xc0 ) {
2884 					address = LOAD_RM16(modrm);
2885 					ea = i386_translate( CS, address );
2886 				} else {
2887 					ea = GetEA(modrm);
2888 				}
2889 				I.idtr.limit = READ16(ea);
2890 				I.idtr.base = READ32(ea + 2) & 0xffffff;
2891 				CYCLES(CYCLES_LIDT);
2892 				break;
2893 			}
2894 		case 4:			/* SMSW */
2895 			{
2896 				if( modrm >= 0xc0 ) {
2897 					STORE_RM16(modrm, I.cr[0]);
2898 					CYCLES(CYCLES_SMSW_REG);
2899 				} else {
2900 					UINT32 ea_ = GetEA(modrm);
2901 					WRITE16(ea_, I.cr[0]);
2902 					CYCLES(CYCLES_SMSW_MEM);
2903 				}
2904 				break;
2905 			}
2906 		case 6:			/* LMSW */
2907 			{
2908 				// TODO: Check for protection fault
2909 				UINT8 b;
2910 				if( modrm >= 0xc0 ) {
2911 					b = LOAD_RM8(modrm);
2912 					CYCLES(CYCLES_LMSW_REG);
2913 				} else {
2914 					ea = GetEA(modrm);
2915 					CYCLES(CYCLES_LMSW_MEM);
2916 				b = READ8(ea);
2917 				}
2918 				I.cr[0] &= ~0x03;
2919 				I.cr[0] |= b & 0x03;
2920 				break;
2921 			}
2922 		default:
2923 		//	osd_die("i386: unimplemented opcode 0x0f 01 /%d at %08X\n", (modrm >> 3) & 0x7, I.eip - 2);
2924 			break;
2925 	}
2926 }
2927 
I386OP(group0FBA_16)2928 static void I386OP(group0FBA_16)(void)		// Opcode 0x0f ba
2929 {
2930 	UINT8 modrm = FETCH();
2931 
2932 	switch( (modrm >> 3) & 0x7 )
2933 	{
2934 		case 4:			/* BT Rm16, i8 */
2935 			if( modrm >= 0xc0 ) {
2936 				UINT16 dst = LOAD_RM16(modrm);
2937 				UINT8 bit = FETCH();
2938 
2939 				if( dst & (1 << bit) )
2940 					I.CF = 1;
2941 				else
2942 					I.CF = 0;
2943 
2944 				CYCLES(CYCLES_BT_IMM_REG);
2945 			} else {
2946 				UINT32 ea = GetEA(modrm);
2947 				UINT16 dst = READ16(ea);
2948 				UINT8 bit = FETCH();
2949 
2950 				if( dst & (1 << bit) )
2951 					I.CF = 1;
2952 				else
2953 					I.CF = 0;
2954 
2955 				CYCLES(CYCLES_BT_IMM_MEM);
2956 			}
2957 			break;
2958 		case 5:			/* BTS Rm16, i8 */
2959 			if( modrm >= 0xc0 ) {
2960 				UINT16 dst = LOAD_RM16(modrm);
2961 				UINT8 bit = FETCH();
2962 
2963 				if( dst & (1 << bit) )
2964 					I.CF = 1;
2965 				else
2966 					I.CF = 0;
2967 				dst |= (1 << bit);
2968 
2969 				STORE_RM16(modrm, dst);
2970 				CYCLES(CYCLES_BTS_IMM_REG);
2971 			} else {
2972 				UINT32 ea = GetEA(modrm);
2973 				UINT16 dst = READ16(ea);
2974 				UINT8 bit = FETCH();
2975 
2976 				if( dst & (1 << bit) )
2977 					I.CF = 1;
2978 				else
2979 					I.CF = 0;
2980 				dst |= (1 << bit);
2981 
2982 				WRITE16(ea, dst);
2983 				CYCLES(CYCLES_BTS_IMM_MEM);
2984 			}
2985 			break;
2986 		case 6:			/* BTR Rm16, i8 */
2987 			if( modrm >= 0xc0 ) {
2988 				UINT16 dst = LOAD_RM16(modrm);
2989 				UINT8 bit = FETCH();
2990 
2991 				if( dst & (1 << bit) )
2992 					I.CF = 1;
2993 				else
2994 					I.CF = 0;
2995 				dst &= ~(1 << bit);
2996 
2997 				STORE_RM16(modrm, dst);
2998 				CYCLES(CYCLES_BTR_IMM_REG);
2999 			} else {
3000 				UINT32 ea = GetEA(modrm);
3001 				UINT16 dst = READ16(ea);
3002 				UINT8 bit = FETCH();
3003 
3004 				if( dst & (1 << bit) )
3005 					I.CF = 1;
3006 				else
3007 					I.CF = 0;
3008 				dst &= ~(1 << bit);
3009 
3010 				WRITE16(ea, dst);
3011 				CYCLES(CYCLES_BTR_IMM_MEM);
3012 			}
3013 			break;
3014 		case 7:			/* BTC Rm16, i8 */
3015 			if( modrm >= 0xc0 ) {
3016 				UINT16 dst = LOAD_RM16(modrm);
3017 				UINT8 bit = FETCH();
3018 
3019 				if( dst & (1 << bit) )
3020 					I.CF = 1;
3021 				else
3022 					I.CF = 0;
3023 				dst ^= (1 << bit);
3024 
3025 				STORE_RM16(modrm, dst);
3026 				CYCLES(CYCLES_BTC_IMM_REG);
3027 			} else {
3028 				UINT32 ea = GetEA(modrm);
3029 				UINT16 dst = READ16(ea);
3030 				UINT8 bit = FETCH();
3031 
3032 				if( dst & (1 << bit) )
3033 					I.CF = 1;
3034 				else
3035 					I.CF = 0;
3036 				dst ^= (1 << bit);
3037 
3038 				WRITE16(ea, dst);
3039 				CYCLES(CYCLES_BTC_IMM_MEM);
3040 			}
3041 			break;
3042 		default:
3043 		//	osd_die("i386: group0FBA_16 /%d unknown\n", (modrm >> 3) & 0x7);
3044 			break;
3045 	}
3046 }
3047 
I386OP(bound_r16_m16_m16)3048 static void I386OP(bound_r16_m16_m16)(void)	// Opcode 0x62
3049 {
3050 	UINT8 modrm;
3051 	INT16 val, low, high;
3052 
3053 	modrm = FETCH();
3054 
3055 	if (modrm >= 0xc0)
3056 	{
3057 		low = high = LOAD_RM16(modrm);
3058 	}
3059 	else
3060 	{
3061 		UINT32 ea = GetEA(modrm);
3062 		low = READ16(ea + 0);
3063 		high = READ16(ea + 2);
3064 	}
3065 	val = LOAD_REG16(modrm);
3066 
3067 	if ((val < low) || (val > high))
3068 	{
3069 		CYCLES(CYCLES_BOUND_OUT_RANGE);
3070 		i386_trap(5, 0);
3071 	}
3072 	else
3073 	{
3074 		CYCLES(CYCLES_BOUND_IN_RANGE);
3075 	}
3076 }
3077 
I386OP(retf16)3078 static void I386OP(retf16)(void)			// Opcode 0xcb
3079 {
3080 	I.eip = POP16();
3081 	I.sreg[CS].selector = POP16();
3082 	i386_load_segment_descriptor( CS );
3083 	CHANGE_PC(I.eip);
3084 
3085 	CYCLES(CYCLES_RET_INTERSEG);
3086 }
3087 
I386OP(retf_i16)3088 static void I386OP(retf_i16)(void)			// Opcode 0xca
3089 {
3090 	UINT16 count = FETCH16();
3091 
3092 	I.eip = POP16();
3093 	I.sreg[CS].selector = POP16();
3094 	i386_load_segment_descriptor( CS );
3095 	CHANGE_PC(I.eip);
3096 
3097 	REG16(SP) += count;
3098 	CYCLES(CYCLES_RET_IMM_INTERSEG);
3099 }
3100 
I386OP(xlat16)3101 static void I386OP(xlat16)(void)			// Opcode 0xd7
3102 {
3103 	UINT32 ea;
3104 	if( I.segment_prefix ) {
3105 		ea = i386_translate( I.segment_override, REG16(BX) + REG8(AL) );
3106 	} else {
3107 		ea = i386_translate( DS, REG16(BX) + REG8(AL) );
3108 	}
3109 	REG8(AL) = READ8(ea);
3110 	CYCLES(CYCLES_XLAT);
3111 }
3112 
I386OP(load_far_pointer16)3113 static void I386OP(load_far_pointer16)(int s)
3114 {
3115 	UINT8 modrm = FETCH();
3116 
3117 	if( modrm >= 0xc0 ) {
3118 	//	osd_die("NYI");
3119 	} else {
3120 		UINT32 ea = GetEA(modrm);
3121 		STORE_REG16(modrm, READ16(ea + 0));
3122 		I.sreg[s].selector = READ16(ea + 2);
3123 		i386_load_segment_descriptor( s );
3124 	}
3125 }
3126 
I386OP(lds16)3127 static void I386OP(lds16)(void)				// Opcode 0xc5
3128 {
3129 	I386OP(load_far_pointer16)(DS);
3130 	CYCLES(CYCLES_LDS);
3131 }
3132 
I386OP(lss16)3133 static void I386OP(lss16)(void)				// Opcode 0x0f 0xb2
3134 {
3135 	I386OP(load_far_pointer16)(SS);
3136 	CYCLES(CYCLES_LSS);
3137 }
3138 
I386OP(les16)3139 static void I386OP(les16)(void)				// Opcode 0xc4
3140 {
3141 	I386OP(load_far_pointer16)(ES);
3142 	CYCLES(CYCLES_LES);
3143 }
3144 
I386OP(lfs16)3145 static void I386OP(lfs16)(void)				// Opcode 0x0f 0xb4
3146 {
3147 	I386OP(load_far_pointer16)(FS);
3148 	CYCLES(CYCLES_LFS);
3149 }
3150 
I386OP(lgs16)3151 static void I386OP(lgs16)(void)				// Opcode 0x0f 0xb5
3152 {
3153 	I386OP(load_far_pointer16)(GS);
3154 	CYCLES(CYCLES_LGS);
3155 }
3156 
3157