I386OP(shift_rotate8)1 static UINT8 I386OP(shift_rotate8)(UINT8 modrm, UINT32 value, UINT8 shift)
2 {
3 	UINT8 src = value;
4 	UINT8 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 rm8, 1 */
13 				I.CF = (src & 0x80) ? 1 : 0;
14 				dst = (src << 1) + I.CF;
15 				I.OF = ((src ^ dst) & 0x80) ? 1 : 0;
16 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
17 				break;
18 			case 1:			/* ROR rm8, 1 */
19 				I.CF = (src & 0x1) ? 1 : 0;
20 				dst = (I.CF << 7) | (src >> 1);
21 				I.OF = ((src ^ dst) & 0x80) ? 1 : 0;
22 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
23 				break;
24 			case 2:			/* RCL rm8, 1 */
25 				dst = (src << 1) + I.CF;
26 				I.CF = (src & 0x80) ? 1 : 0;
27 				I.OF = ((src ^ dst) & 0x80) ? 1 : 0;
28 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
29 				break;
30 			case 3:			/* RCR rm8, 1 */
31 				dst = (I.CF << 7) | (src >> 1);
32 				I.CF = src & 0x1;
33 				I.OF = ((src ^ dst) & 0x80) ? 1 : 0;
34 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
35 				break;
36 			case 4:			/* SHL/SAL rm8, 1 */
37 			case 6:
38 				dst = src << 1;
39 				I.CF = (src & 0x80) ? 1 : 0;
40 				I.OF = (((I.CF << 7) ^ dst) & 0x80) ? 1 : 0;
41 				SetSZPF8(dst);
42 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
43 				break;
44 			case 5:			/* SHR rm8, 1 */
45 				dst = src >> 1;
46 				I.CF = src & 0x1;
47 				I.OF = (dst & 0x80) ? 1 : 0;
48 				SetSZPF8(dst);
49 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
50 				break;
51 			case 7:			/* SAR rm8, 1 */
52 				dst = (INT8)(src) >> 1;
53 				I.CF = src & 0x1;
54 				I.OF = 0;
55 				SetSZPF8(dst);
56 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
57 				break;
58 		}
59 
60 	} else {
61 
62 		switch( (modrm >> 3) & 0x7 )
63 		{
64 			case 0:			/* ROL rm8, i8 */
65 				dst = ((src & ((UINT8)0xff >> shift)) << shift) |
66 					  ((src & ((UINT8)0xff << (8-shift))) >> (8-shift));
67 				I.CF = (src >> (8-shift)) & 0x1;
68 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
69 				break;
70 			case 1:			/* ROR rm8, i8 */
71 				dst = ((src & ((UINT8)0xff << shift)) >> shift) |
72 					  ((src & ((UINT8)0xff >> (8-shift))) << (8-shift));
73 				I.CF = (src >> (shift-1)) & 0x1;
74 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
75 				break;
76 			case 2:			/* RCL rm8, i8 */
77 				dst = ((src & ((UINT8)0xff >> shift)) << shift) |
78 					  ((src & ((UINT8)0xff << (9-shift))) >> (9-shift)) |
79 					  (I.CF << (shift-1));
80 				I.CF = (src >> (8-shift)) & 0x1;
81 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
82 				break;
83 			case 3:			/* RCR rm8, i8 */
84 				dst = ((src & ((UINT8)0xff << shift)) >> shift) |
85 					  ((src & ((UINT8)0xff >> (8-shift))) << (9-shift)) |
86 					  (I.CF << (8-shift));
87 				I.CF = (src >> (shift-1)) & 0x1;
88 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
89 				break;
90 			case 4:			/* SHL/SAL rm8, i8 */
91 			case 6:
92 				dst = src << shift;
93 				I.CF = (src & (1 << (8-shift))) ? 1 : 0;
94 				SetSZPF8(dst);
95 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
96 				break;
97 			case 5:			/* SHR rm8, i8 */
98 				dst = src >> shift;
99 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
100 				SetSZPF8(dst);
101 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
102 				break;
103 			case 7:			/* SAR rm8, i8 */
104 				dst = (INT8)src >> shift;
105 				I.CF = (src & (1 << (shift-1))) ? 1 : 0;
106 				SetSZPF8(dst);
107 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
108 				break;
109 		}
110 	}
111 
112 	return dst;
113 }
114 
115 
116 
I386OP(adc_rm8_r8)117 static void I386OP(adc_rm8_r8)(void)		// Opcode 0x10
118 {
119 	UINT8 src, dst;
120 	UINT8 modrm = FETCH();
121 	if( modrm >= 0xc0 ) {
122 		src = LOAD_REG8(modrm);
123 		dst = LOAD_RM8(modrm);
124 		src = ADD8(src, I.CF);
125 		dst = ADD8(dst, src);
126 		STORE_RM8(modrm, dst);
127 		CYCLES(CYCLES_ALU_REG_REG);
128 	} else {
129 		UINT32 ea = GetEA(modrm);
130 		src = LOAD_REG8(modrm);
131 		dst = READ8(ea);
132 		src = ADD8(src, I.CF);
133 		dst = ADD8(dst, src);
134 		WRITE8(ea, dst);
135 		CYCLES(CYCLES_ALU_REG_MEM);
136 	}
137 }
138 
I386OP(adc_r8_rm8)139 static void I386OP(adc_r8_rm8)(void)		// Opcode 0x12
140 {
141 	UINT8 src, dst;
142 	UINT8 modrm = FETCH();
143 	if( modrm >= 0xc0 ) {
144 		src = LOAD_RM8(modrm);
145 		dst = LOAD_REG8(modrm);
146 		src = ADD8(src, I.CF);
147 		dst = ADD8(dst, src);
148 		STORE_REG8(modrm, dst);
149 		CYCLES(CYCLES_ALU_REG_REG);
150 	} else {
151 		UINT32 ea = GetEA(modrm);
152 		src = READ8(ea);
153 		dst = LOAD_REG8(modrm);
154 		src = ADD8(src, I.CF);
155 		dst = ADD8(dst, src);
156 		STORE_REG8(modrm, dst);
157 		CYCLES(CYCLES_ALU_MEM_REG);
158 	}
159 }
160 
I386OP(adc_al_i8)161 static void I386OP(adc_al_i8)(void)		// Opcode 0x14
162 {
163 	UINT8 src, dst;
164 	src = FETCH();
165 	dst = REG8(AL);
166 	src = ADD8(src, I.CF);
167 	dst = ADD8(dst, src);
168 	REG8(AL) = dst;
169 	CYCLES(CYCLES_ALU_IMM_ACC);
170 }
171 
I386OP(add_rm8_r8)172 static void I386OP(add_rm8_r8)(void)		// Opcode 0x00
173 {
174 	UINT8 src, dst;
175 	UINT8 modrm = FETCH();
176 	if( modrm >= 0xc0 ) {
177 		src = LOAD_REG8(modrm);
178 		dst = LOAD_RM8(modrm);
179 		dst = ADD8(dst, src);
180 		STORE_RM8(modrm, dst);
181 		CYCLES(CYCLES_ALU_REG_REG);
182 	} else {
183 		UINT32 ea = GetEA(modrm);
184 		src = LOAD_REG8(modrm);
185 		dst = READ8(ea);
186 		dst = ADD8(dst, src);
187 		WRITE8(ea, dst);
188 		CYCLES(CYCLES_ALU_REG_MEM);
189 	}
190 }
191 
I386OP(add_r8_rm8)192 static void I386OP(add_r8_rm8)(void)		// Opcode 0x02
193 {
194 	UINT8 src, dst;
195 	UINT8 modrm = FETCH();
196 	if( modrm >= 0xc0 ) {
197 		src = LOAD_RM8(modrm);
198 		dst = LOAD_REG8(modrm);
199 		dst = ADD8(dst, src);
200 		STORE_REG8(modrm, dst);
201 		CYCLES(CYCLES_ALU_REG_REG);
202 	} else {
203 		UINT32 ea = GetEA(modrm);
204 		src = READ8(ea);
205 		dst = LOAD_REG8(modrm);
206 		dst = ADD8(dst, src);
207 		STORE_REG8(modrm, dst);
208 		CYCLES(CYCLES_ALU_MEM_REG);
209 	}
210 }
211 
I386OP(add_al_i8)212 static void I386OP(add_al_i8)(void)		// Opcode 0x04
213 {
214 	UINT8 src, dst;
215 	src = FETCH();
216 	dst = REG8(AL);
217 	dst = ADD8(dst, src);
218 	REG8(AL) = dst;
219 	CYCLES(CYCLES_ALU_IMM_ACC);
220 }
221 
I386OP(and_rm8_r8)222 static void I386OP(and_rm8_r8)(void)		// Opcode 0x20
223 {
224 	UINT8 src, dst;
225 	UINT8 modrm = FETCH();
226 	if( modrm >= 0xc0 ) {
227 		src = LOAD_REG8(modrm);
228 		dst = LOAD_RM8(modrm);
229 		dst = AND8(dst, src);
230 		STORE_RM8(modrm, dst);
231 		CYCLES(CYCLES_ALU_REG_REG);
232 	} else {
233 		UINT32 ea = GetEA(modrm);
234 		src = LOAD_REG8(modrm);
235 		dst = READ8(ea);
236 		dst = AND8(dst, src);
237 		WRITE8(ea, dst);
238 		CYCLES(CYCLES_ALU_REG_MEM);
239 	}
240 }
241 
I386OP(and_r8_rm8)242 static void I386OP(and_r8_rm8)(void)		// Opcode 0x22
243 {
244 	UINT8 src, dst;
245 	UINT8 modrm = FETCH();
246 	if( modrm >= 0xc0 ) {
247 		src = LOAD_RM8(modrm);
248 		dst = LOAD_REG8(modrm);
249 		dst = AND8(dst, src);
250 		STORE_REG8(modrm, dst);
251 		CYCLES(CYCLES_ALU_REG_REG);
252 	} else {
253 		UINT32 ea = GetEA(modrm);
254 		src = READ8(ea);
255 		dst = LOAD_REG8(modrm);
256 		dst = AND8(dst, src);
257 		STORE_REG8(modrm, dst);
258 		CYCLES(CYCLES_ALU_MEM_REG);
259 	}
260 }
261 
I386OP(and_al_i8)262 static void I386OP(and_al_i8)(void)			// Opcode 0x24
263 {
264 	UINT8 src, dst;
265 	src = FETCH();
266 	dst = REG8(AL);
267 	dst = AND8(dst, src);
268 	REG8(AL) = dst;
269 	CYCLES(CYCLES_ALU_IMM_ACC);
270 }
271 
I386OP(clc)272 static void I386OP(clc)(void)				// Opcode 0xf8
273 {
274 	I.CF = 0;
275 	CYCLES(CYCLES_CLC);
276 }
277 
I386OP(cld)278 static void I386OP(cld)(void)				// Opcode 0xfc
279 {
280 	I.DF = 0;
281 	CYCLES(CYCLES_CLD);
282 }
283 
I386OP(cli)284 static void I386OP(cli)(void)				// Opcode 0xfa
285 {
286 	I.IF = 0;
287 	CYCLES(CYCLES_CLI);
288 }
289 
I386OP(cmc)290 static void I386OP(cmc)(void)				// Opcode 0xf5
291 {
292 	I.CF ^= 1;
293 	CYCLES(CYCLES_CMC);
294 }
295 
I386OP(cmp_rm8_r8)296 static void I386OP(cmp_rm8_r8)(void)		// Opcode 0x38
297 {
298 	UINT8 src, dst;
299 	UINT8 modrm = FETCH();
300 	if( modrm >= 0xc0 ) {
301 		src = LOAD_REG8(modrm);
302 		dst = LOAD_RM8(modrm);
303 		SUB8(dst, src);
304 		CYCLES(CYCLES_CMP_REG_REG);
305 	} else {
306 		UINT32 ea = GetEA(modrm);
307 		src = LOAD_REG8(modrm);
308 		dst = READ8(ea);
309 		SUB8(dst, src);
310 		CYCLES(CYCLES_CMP_REG_MEM);
311 	}
312 }
313 
I386OP(cmp_r8_rm8)314 static void I386OP(cmp_r8_rm8)(void)		// Opcode 0x3a
315 {
316 	UINT8 src, dst;
317 	UINT8 modrm = FETCH();
318 	if( modrm >= 0xc0 ) {
319 		src = LOAD_RM8(modrm);
320 		dst = LOAD_REG8(modrm);
321 		SUB8(dst, src);
322 		CYCLES(CYCLES_CMP_REG_REG);
323 	} else {
324 		UINT32 ea = GetEA(modrm);
325 		src = READ8(ea);
326 		dst = LOAD_REG8(modrm);
327 		SUB8(dst, src);
328 		CYCLES(CYCLES_CMP_MEM_REG);
329 	}
330 }
331 
I386OP(cmp_al_i8)332 static void I386OP(cmp_al_i8)(void)			// Opcode 0x3c
333 {
334 	UINT8 src, dst;
335 	src = FETCH();
336 	dst = REG8(AL);
337 	SUB8(dst, src);
338 	CYCLES(CYCLES_CMP_IMM_ACC);
339 }
340 
I386OP(cmpsb)341 static void I386OP(cmpsb)(void)				// Opcode 0xa6
342 {
343 	UINT32 eas, ead;
344 	UINT8 src, dst;
345 	if( I.segment_prefix ) {
346 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
347 	} else {
348 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
349 	}
350 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
351 	src = READ8(eas);
352 	dst = READ8(ead);
353 	SUB8(dst, src);
354 	BUMP_SI(1);
355 	BUMP_DI(1);
356 	CYCLES(CYCLES_CMPS);
357 }
358 
I386OP(in_al_i8)359 static void I386OP(in_al_i8)(void)			// Opcode 0xe4
360 {
361 	UINT16 port = FETCH();
362 	UINT8 data = READPORT8(port);
363 	REG8(AL) = data;
364 	CYCLES(CYCLES_IN_VAR);
365 }
366 
I386OP(in_al_dx)367 static void I386OP(in_al_dx)(void)			// Opcode 0xec
368 {
369 	UINT16 port = REG16(DX);
370 	UINT8 data = READPORT8(port);
371 	REG8(AL) = data;
372 	CYCLES(CYCLES_IN);
373 }
374 
I386OP(ja_rel8)375 static void I386OP(ja_rel8)(void)			// Opcode 0x77
376 {
377 	INT8 disp = FETCH();
378 	if( I.CF == 0 && I.ZF == 0 ) {
379 		NEAR_BRANCH(disp);
380 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
381 	} else {
382 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
383 	}
384 }
385 
I386OP(jbe_rel8)386 static void I386OP(jbe_rel8)(void)			// Opcode 0x76
387 {
388 	INT8 disp = FETCH();
389 	if( I.CF != 0 || I.ZF != 0 ) {
390 		NEAR_BRANCH(disp);
391 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
392 	} else {
393 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
394 	}
395 }
396 
I386OP(jc_rel8)397 static void I386OP(jc_rel8)(void)			// Opcode 0x72
398 {
399 	INT8 disp = FETCH();
400 	if( I.CF != 0 ) {
401 		NEAR_BRANCH(disp);
402 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
403 	} else {
404 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
405 	}
406 }
407 
I386OP(jg_rel8)408 static void I386OP(jg_rel8)(void)			// Opcode 0x7f
409 {
410 	INT8 disp = FETCH();
411 	if( I.ZF == 0 && (I.SF == I.OF) ) {
412 		NEAR_BRANCH(disp);
413 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
414 	} else {
415 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
416 	}
417 }
418 
I386OP(jge_rel8)419 static void I386OP(jge_rel8)(void)			// Opcode 0x7d
420 {
421 	INT8 disp = FETCH();
422 	if( (I.SF == I.OF) ) {
423 		NEAR_BRANCH(disp);
424 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
425 	} else {
426 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
427 	}
428 }
429 
I386OP(jl_rel8)430 static void I386OP(jl_rel8)(void)			// Opcode 0x7c
431 {
432 	INT8 disp = FETCH();
433 	if( (I.SF != I.OF) ) {
434 		NEAR_BRANCH(disp);
435 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
436 	} else {
437 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
438 	}
439 }
440 
I386OP(jle_rel8)441 static void I386OP(jle_rel8)(void)		// Opcode 0x7e
442 {
443 	INT8 disp = FETCH();
444 	if( I.ZF != 0 || (I.SF != I.OF) ) {
445 		NEAR_BRANCH(disp);
446 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
447 	} else {
448 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
449 	}
450 }
451 
I386OP(jnc_rel8)452 static void I386OP(jnc_rel8)(void)			// Opcode 0x73
453 {
454 	INT8 disp = FETCH();
455 	if( I.CF == 0 ) {
456 		NEAR_BRANCH(disp);
457 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
458 	} else {
459 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
460 	}
461 }
462 
I386OP(jno_rel8)463 static void I386OP(jno_rel8)(void)			// Opcode 0x71
464 {
465 	INT8 disp = FETCH();
466 	if( I.OF == 0 ) {
467 		NEAR_BRANCH(disp);
468 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
469 	} else {
470 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
471 	}
472 }
473 
I386OP(jnp_rel8)474 static void I386OP(jnp_rel8)(void)			// Opcode 0x7b
475 {
476 	INT8 disp = FETCH();
477 	if( I.PF == 0 ) {
478 		NEAR_BRANCH(disp);
479 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
480 	} else {
481 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
482 	}
483 }
484 
I386OP(jns_rel8)485 static void I386OP(jns_rel8)(void)			// Opcode 0x79
486 {
487 	INT8 disp = FETCH();
488 	if( I.SF == 0 ) {
489 		NEAR_BRANCH(disp);
490 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
491 	} else {
492 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
493 	}
494 }
495 
I386OP(jnz_rel8)496 static void I386OP(jnz_rel8)(void)			// Opcode 0x75
497 {
498 	INT8 disp = FETCH();
499 	if( I.ZF == 0 ) {
500 		NEAR_BRANCH(disp);
501 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
502 	} else {
503 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
504 	}
505 }
506 
I386OP(jo_rel8)507 static void I386OP(jo_rel8)(void)			// Opcode 0x70
508 {
509 	INT8 disp = FETCH();
510 	if( I.OF != 0 ) {
511 		NEAR_BRANCH(disp);
512 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
513 	} else {
514 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
515 	}
516 }
517 
I386OP(jp_rel8)518 static void I386OP(jp_rel8)(void)			// Opcode 0x7a
519 {
520 	INT8 disp = FETCH();
521 	if( I.PF != 0 ) {
522 		NEAR_BRANCH(disp);
523 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
524 	} else {
525 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
526 	}
527 }
528 
I386OP(js_rel8)529 static void I386OP(js_rel8)(void)			// Opcode 0x78
530 {
531 	INT8 disp = FETCH();
532 	if( I.SF != 0 ) {
533 		NEAR_BRANCH(disp);
534 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
535 	} else {
536 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
537 	}
538 }
539 
I386OP(jz_rel8)540 static void I386OP(jz_rel8)(void)			// Opcode 0x74
541 {
542 	INT8 disp = FETCH();
543 	if( I.ZF != 0 ) {
544 		NEAR_BRANCH(disp);
545 		CYCLES(CYCLES_JCC_DISP8);		/* TODO: Timing = 7 + m */
546 	} else {
547 		CYCLES(CYCLES_JCC_DISP8_NOBRANCH);
548 	}
549 }
550 
I386OP(jmp_rel8)551 static void I386OP(jmp_rel8)(void)			// Opcode 0xeb
552 {
553 	INT8 disp = FETCH();
554 	NEAR_BRANCH(disp);
555 	CYCLES(CYCLES_JMP_SHORT);		/* TODO: Timing = 7 + m */
556 }
557 
I386OP(lahf)558 static void I386OP(lahf)(void)				// Opcode 0x9f
559 {
560 	REG8(AH) = get_flags() & 0xd7;
561 	CYCLES(CYCLES_LAHF);
562 }
563 
I386OP(lodsb)564 static void I386OP(lodsb)(void)				// Opcode 0xac
565 {
566 	UINT32 eas;
567 	if( I.segment_prefix ) {
568 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
569 	} else {
570 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
571 	}
572 	REG8(AL) = READ8(eas);
573 	BUMP_SI(1);
574 	CYCLES(CYCLES_LODS);
575 }
576 
I386OP(mov_rm8_r8)577 static void I386OP(mov_rm8_r8)(void)		// Opcode 0x88
578 {
579 	UINT8 src;
580 	UINT8 modrm = FETCH();
581 	if( modrm >= 0xc0 ) {
582 		src = LOAD_REG8(modrm);
583 		STORE_RM8(modrm, src);
584 		CYCLES(CYCLES_MOV_REG_REG);
585 	} else {
586 		UINT32 ea = GetEA(modrm);
587 		src = LOAD_REG8(modrm);
588 		WRITE8(ea, src);
589 		CYCLES(CYCLES_MOV_REG_MEM);
590 	}
591 }
592 
I386OP(mov_r8_rm8)593 static void I386OP(mov_r8_rm8)(void)		// Opcode 0x8a
594 {
595 	UINT8 src;
596 	UINT8 modrm = FETCH();
597 	if( modrm >= 0xc0 ) {
598 		src = LOAD_RM8(modrm);
599 		STORE_REG8(modrm, src);
600 		CYCLES(CYCLES_MOV_REG_REG);
601 	} else {
602 		UINT32 ea = GetEA(modrm);
603 		src = READ8(ea);
604 		STORE_REG8(modrm, src);
605 		CYCLES(CYCLES_MOV_MEM_REG);
606 	}
607 }
608 
I386OP(mov_rm8_i8)609 static void I386OP(mov_rm8_i8)(void)		// Opcode 0xc6
610 {
611 	UINT8 modrm = FETCH();
612 	if( modrm >= 0xc0 ) {
613 		UINT8 value = FETCH();
614 		STORE_RM8(modrm, value);
615 		CYCLES(CYCLES_MOV_IMM_REG);
616 	} else {
617 		UINT32 ea = GetEA(modrm);
618 		UINT8 value = FETCH();
619 		WRITE8(ea, value);
620 		CYCLES(CYCLES_MOV_IMM_MEM);
621 	}
622 }
623 
I386OP(mov_r32_cr)624 static void I386OP(mov_r32_cr)(void)		// Opcode 0x0f 20
625 {
626 	UINT8 modrm = FETCH();
627 	UINT8 cr = (modrm >> 3) & 0x7;
628 
629 	STORE_RM32(modrm, I.cr[cr]);
630 	CYCLES(CYCLES_MOV_CR_REG);
631 }
632 
I386OP(mov_r32_dr)633 static void I386OP(mov_r32_dr)(void)		// Opcode 0x0f 21
634 {
635 	UINT8 modrm = FETCH();
636 	UINT8 dr = (modrm >> 3) & 0x7;
637 
638 	STORE_RM32(modrm, I.dr[dr]);
639 	switch(dr)
640 	{
641 		case 0:
642 		case 1:
643 		case 2:
644 		case 3:
645 			CYCLES(CYCLES_MOV_REG_DR0_3);
646 			break;
647 		case 6:
648 		case 7:
649 			CYCLES(CYCLES_MOV_REG_DR6_7);
650 			break;
651 	}
652 }
653 
I386OP(mov_cr_r32)654 static void I386OP(mov_cr_r32)(void)		// Opcode 0x0f 22
655 {
656 	UINT8 modrm = FETCH();
657 	UINT8 cr = (modrm >> 3) & 0x7;
658 
659 	I.cr[cr] = LOAD_RM32(modrm);
660 	switch(cr)
661 	{
662 		case 0: CYCLES(CYCLES_MOV_REG_CR0); break;
663 		case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
664 		case 3: CYCLES(CYCLES_MOV_REG_CR3); break;
665 		default:
666 		//	osd_die("i386: mov_cr_r32 CR%d !\n", cr);
667 			break;
668 	}
669 }
670 
I386OP(mov_dr_r32)671 static void I386OP(mov_dr_r32)(void)		// Opcode 0x0f 23
672 {
673 	UINT8 modrm = FETCH();
674 	UINT8 dr = (modrm >> 3) & 0x7;
675 
676 	I.dr[dr] = LOAD_RM32(modrm);
677 	switch(dr)
678 	{
679 		case 0:
680 		case 1:
681 		case 2:
682 		case 3:
683 			CYCLES(CYCLES_MOV_DR0_3_REG);
684 			break;
685 		case 6:
686 		case 7:
687 			CYCLES(CYCLES_MOV_DR6_7_REG);
688 			break;
689 		default:
690 		//	osd_die("i386: mov_dr_r32 DR%d !\n", dr);
691 			break;
692 	}
693 }
694 
I386OP(mov_al_m8)695 static void I386OP(mov_al_m8)(void)			// Opcode 0xa0
696 {
697 	UINT32 offset, ea;
698 	if( I.address_size ) {
699 		offset = FETCH32();
700 	} else {
701 		offset = FETCH16();
702 	}
703 	/* TODO: Not sure if this is correct... */
704 	if( I.segment_prefix ) {
705 		ea = i386_translate( I.segment_override, offset );
706 	} else {
707 		ea = i386_translate( DS, offset );
708 	}
709 	REG8(AL) = READ8(ea);
710 	CYCLES(CYCLES_MOV_IMM_MEM);
711 }
712 
I386OP(mov_m8_al)713 static void I386OP(mov_m8_al)(void)			// Opcode 0xa2
714 {
715 	UINT32 offset, ea;
716 	if( I.address_size ) {
717 		offset = FETCH32();
718 	} else {
719 		offset = FETCH16();
720 	}
721 	/* TODO: Not sure if this is correct... */
722 	if( I.segment_prefix ) {
723 		ea = i386_translate( I.segment_override, offset );
724 	} else {
725 		ea = i386_translate( DS, offset );
726 	}
727 	WRITE8( ea, REG8(AL) );
728 	CYCLES(CYCLES_MOV_MEM_ACC);
729 }
730 
I386OP(mov_rm16_sreg)731 static void I386OP(mov_rm16_sreg)(void)		// Opcode 0x8c
732 {
733 	UINT8 modrm = FETCH();
734 	int s = (modrm >> 3) & 0x7;
735 
736 	if( modrm >= 0xc0 ) {
737 		STORE_RM16(modrm, I.sreg[s].selector);
738 		CYCLES(CYCLES_MOV_SREG_REG);
739 	} else {
740 		UINT32 ea = GetEA(modrm);
741 		WRITE16(ea, I.sreg[s].selector);
742 		CYCLES(CYCLES_MOV_SREG_MEM);
743 	}
744 }
745 
I386OP(mov_sreg_rm16)746 static void I386OP(mov_sreg_rm16)(void)		// Opcode 0x8e
747 {
748 	UINT16 selector;
749 	UINT8 modrm = FETCH();
750 	int s = (modrm >> 3) & 0x7;
751 
752 	if( modrm >= 0xc0 ) {
753 		selector = LOAD_RM16(modrm);
754 		CYCLES(CYCLES_MOV_REG_SREG);
755 	} else {
756 		UINT32 ea = GetEA(modrm);
757 		selector = READ16(ea);
758 		CYCLES(CYCLES_MOV_MEM_SREG);
759 	}
760 	I.sreg[s].selector = selector;
761 	i386_load_segment_descriptor( s );
762 }
763 
I386OP(mov_al_i8)764 static void I386OP(mov_al_i8)(void)			// Opcode 0xb0
765 {
766 	REG8(AL) = FETCH();
767 	CYCLES(CYCLES_MOV_IMM_REG);
768 }
769 
I386OP(mov_cl_i8)770 static void I386OP(mov_cl_i8)(void)			// Opcode 0xb1
771 {
772 	REG8(CL) = FETCH();
773 	CYCLES(CYCLES_MOV_IMM_REG);
774 }
775 
I386OP(mov_dl_i8)776 static void I386OP(mov_dl_i8)(void)			// Opcode 0xb2
777 {
778 	REG8(DL) = FETCH();
779 	CYCLES(CYCLES_MOV_IMM_REG);
780 }
781 
I386OP(mov_bl_i8)782 static void I386OP(mov_bl_i8)(void)			// Opcode 0xb3
783 {
784 	REG8(BL) = FETCH();
785 	CYCLES(CYCLES_MOV_IMM_REG);
786 }
787 
I386OP(mov_ah_i8)788 static void I386OP(mov_ah_i8)(void)			// Opcode 0xb4
789 {
790 	REG8(AH) = FETCH();
791 	CYCLES(CYCLES_MOV_IMM_REG);
792 }
793 
I386OP(mov_ch_i8)794 static void I386OP(mov_ch_i8)(void)			// Opcode 0xb5
795 {
796 	REG8(CH) = FETCH();
797 	CYCLES(CYCLES_MOV_IMM_REG);
798 }
799 
I386OP(mov_dh_i8)800 static void I386OP(mov_dh_i8)(void)			// Opcode 0xb6
801 {
802 	REG8(DH) = FETCH();
803 	CYCLES(CYCLES_MOV_IMM_REG);
804 }
805 
I386OP(mov_bh_i8)806 static void I386OP(mov_bh_i8)(void)			// Opcode 0xb7
807 {
808 	REG8(BH) = FETCH();
809 	CYCLES(CYCLES_MOV_IMM_REG);
810 }
811 
I386OP(movsb)812 static void I386OP(movsb)(void)				// Opcode 0xa4
813 {
814 	UINT32 eas, ead;
815 	UINT8 v;
816 	if( I.segment_prefix ) {
817 		eas = i386_translate( I.segment_override, I.address_size ? REG32(ESI) : REG16(SI) );
818 	} else {
819 		eas = i386_translate( DS, I.address_size ? REG32(ESI) : REG16(SI) );
820 	}
821 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
822 	v = READ8(eas);
823 	WRITE8(ead, v);
824 	BUMP_SI(1);
825 	BUMP_DI(1);
826 	CYCLES(CYCLES_MOVS);
827 }
828 
I386OP(or_rm8_r8)829 static void I386OP(or_rm8_r8)(void)			// Opcode 0x08
830 {
831 	UINT8 src, dst;
832 	UINT8 modrm = FETCH();
833 	if( modrm >= 0xc0 ) {
834 		src = LOAD_REG8(modrm);
835 		dst = LOAD_RM8(modrm);
836 		dst = OR8(dst, src);
837 		STORE_RM8(modrm, dst);
838 		CYCLES(CYCLES_ALU_REG_REG);
839 	} else {
840 		UINT32 ea = GetEA(modrm);
841 		src = LOAD_REG8(modrm);
842 		dst = READ8(ea);
843 		dst = OR8(dst, src);
844 		WRITE8(ea, dst);
845 		CYCLES(CYCLES_ALU_REG_MEM);
846 	}
847 }
848 
I386OP(or_r8_rm8)849 static void I386OP(or_r8_rm8)(void)			// Opcode 0x0a
850 {
851 	UINT8 src, dst;
852 	UINT8 modrm = FETCH();
853 	if( modrm >= 0xc0 ) {
854 		src = LOAD_RM8(modrm);
855 		dst = LOAD_REG8(modrm);
856 		dst = OR8(dst, src);
857 		STORE_REG8(modrm, dst);
858 		CYCLES(CYCLES_ALU_REG_REG);
859 	} else {
860 		UINT32 ea = GetEA(modrm);
861 		src = READ8(ea);
862 		dst = LOAD_REG8(modrm);
863 		dst = OR8(dst, src);
864 		STORE_REG8(modrm, dst);
865 		CYCLES(CYCLES_ALU_MEM_REG);
866 	}
867 }
868 
I386OP(or_al_i8)869 static void I386OP(or_al_i8)(void)			// Opcode 0x0c
870 {
871 	UINT8 src, dst;
872 	src = FETCH();
873 	dst = REG8(AL);
874 	dst = OR8(dst, src);
875 	REG8(AL) = dst;
876 	CYCLES(CYCLES_ALU_IMM_ACC);
877 }
878 
I386OP(out_al_i8)879 static void I386OP(out_al_i8)(void)			// Opcode 0xe6
880 {
881 	UINT16 port = FETCH();
882 	UINT8 data = REG8(AL);
883 	WRITEPORT8(port, data);
884 	CYCLES(CYCLES_OUT_VAR);
885 }
886 
I386OP(out_al_dx)887 static void I386OP(out_al_dx)(void)			// Opcode 0xee
888 {
889 	UINT16 port = REG16(DX);
890 	UINT8 data = REG8(AL);
891 	WRITEPORT8(port, data);
892 	CYCLES(CYCLES_OUT);
893 }
894 
I386OP(push_i8)895 static void I386OP(push_i8)(void)			// Opcode 0x6a
896 {
897 	UINT8 value = FETCH();
898 	PUSH8(value);
899 	CYCLES(CYCLES_PUSH_IMM);
900 }
901 
I386OP(ins_generic)902 static void I386OP(ins_generic)(int size)
903 {
904 	UINT32 ead;
905 	UINT8 vb;
906 	UINT16 vw;
907 	UINT32 vd;
908 
909 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
910 
911 	switch(size) {
912 	case 1:
913 		vb = READPORT8(REG16(DX));
914 		WRITE8(ead, vb);
915 		break;
916 	case 2:
917 		vw = READPORT16(REG16(DX));
918 		WRITE16(ead, vw);
919 		break;
920 	case 4:
921 		vd = READPORT32(REG16(DX));
922 		WRITE32(ead, vd);
923 		break;
924 	}
925 
926 	REG32(EDI) += ((I.DF) ? -1 : 1) * size;
927 	CYCLES(CYCLES_INS);	// TODO: Confirm this value
928 }
929 
I386OP(insb)930 static void I386OP(insb)(void)				// Opcode 0x6c
931 {
932 	I386OP(ins_generic)(1);
933 }
934 
I386OP(insw)935 static void I386OP(insw)(void)				// Opcode 0x6d
936 {
937 	I386OP(ins_generic)(2);
938 }
939 
I386OP(insd)940 static void I386OP(insd)(void)				// Opcode 0x6d
941 {
942 	I386OP(ins_generic)(4);
943 }
944 
I386OP(outs_generic)945 static void I386OP(outs_generic)(int size)
946 {
947 	UINT32 eas;
948 	UINT8 vb;
949 	UINT16 vw;
950 	UINT32 vd;
951 
952 	if( I.segment_prefix ) {
953 		eas = i386_translate( I.segment_override, REG32(ESI) );
954 	} else {
955 		eas = i386_translate( DS, REG32(ESI) );
956 	}
957 
958 	switch(size) {
959 	case 1:
960 		vb = READ8(eas);
961 		WRITEPORT8(REG16(DX), vb);
962 		break;
963 	case 2:
964 		vw = READ16(eas);
965 		WRITEPORT16(REG16(DX), vw);
966 		break;
967 	case 4:
968 		vd = READ32(eas);
969 		WRITEPORT32(REG16(DX), vd);
970 		break;
971 	}
972 
973 	REG32(ESI) += ((I.DF) ? -1 : 1) * size;
974 	CYCLES(CYCLES_OUTS);	// TODO: Confirm this value
975 }
976 
I386OP(outsb)977 static void I386OP(outsb)(void)				// Opcode 0x6e
978 {
979 	I386OP(outs_generic)(1);
980 }
981 
I386OP(outsw)982 static void I386OP(outsw)(void)				// Opcode 0x6f
983 {
984 	I386OP(outs_generic)(2);
985 }
986 
I386OP(outsd)987 static void I386OP(outsd)(void)				// Opcode 0x6f
988 {
989 	I386OP(outs_generic)(4);
990 }
991 
I386OP(repeat)992 static void I386OP(repeat)(int invert_flag)
993 {
994 	UINT32 repeated_eip = I.eip;
995 	UINT32 repeated_pc = I.pc;
996 	UINT8 opcode = FETCH();
997 	UINT32 eas, ead;
998 	UINT32 count;
999 	INT32 cycle_base = 0, cycle_adjustment = 0;
1000 	UINT8 *flag = NULL;
1001 
1002 	if( I.segment_prefix ) {
1003 		eas = i386_translate( I.segment_override, I.sreg[CS].d ? REG32(ESI) : REG16(SI) );
1004 	} else {
1005 		eas = i386_translate( DS, I.sreg[CS].d ? REG32(ESI) : REG16(SI) );
1006 	}
1007 	ead = i386_translate( ES, I.sreg[CS].d ? REG32(EDI) : REG16(DI) );
1008 
1009 	if( opcode == 0x66 ) {
1010 		I.operand_size ^= 1;
1011 		repeated_eip = I.eip;
1012 		repeated_pc = I.pc;
1013 		opcode = FETCH();
1014 	}
1015 	if( opcode == 0x67 ) {
1016 		I.address_size ^= 1;
1017 		repeated_eip = I.eip;
1018 		repeated_pc = I.pc;
1019 		opcode = FETCH();
1020 	}
1021 
1022 	switch(opcode)
1023 	{
1024 		case 0x6c:
1025 		case 0x6d:
1026 			/* INSB, INSW, INSD */
1027 			// TODO: cycle count
1028 			cycle_base = 8;
1029 			cycle_adjustment = -4;
1030 			flag = NULL;
1031 			break;
1032 
1033 		case 0x6e:
1034 		case 0x6f:
1035 			/* OUTSB, OUTSW, OUTSD */
1036 			// TODO: cycle count
1037 			cycle_base = 8;
1038 			cycle_adjustment = -4;
1039 			flag = NULL;
1040 			break;
1041 
1042 		case 0xa4:
1043 		case 0xa5:
1044 			/* MOVSB, MOVSW, MOVSD */
1045 			cycle_base = 8;
1046 			cycle_adjustment = -4;
1047 			flag = NULL;
1048 			break;
1049 
1050 		case 0xa6:
1051 		case 0xa7:
1052 			/* CMPSB, CMPSW, CMPSD */
1053 			cycle_base = 5;
1054 			cycle_adjustment = -1;
1055 			flag = &I.ZF;
1056 			break;
1057 
1058 		case 0xac:
1059 		case 0xad:
1060 			/* LODSB, LODSW, LODSD */
1061 			cycle_base = 5;
1062 			cycle_adjustment = 1;
1063 			flag = NULL;
1064 			break;
1065 
1066 		case 0xaa:
1067 		case 0xab:
1068 			/* STOSB, STOSW, STOSD */
1069 			cycle_base = 5;
1070 			cycle_adjustment = 0;
1071 			flag = NULL;
1072 			break;
1073 
1074 		case 0xae:
1075 		case 0xaf:
1076 			/* SCASB, SCASW, SCASD */
1077 			cycle_base = 5;
1078 			cycle_adjustment = 0;
1079 			flag = &I.ZF;
1080 			break;
1081 
1082 		default:
1083 		//	osd_die("i386: Invalid REP/opcode %02X combination\n",opcode);
1084 			break;
1085 	}
1086 
1087 	if( I.sreg[CS].d ) {
1088 		if( REG32(ECX) == 0 )
1089 			return;
1090 	} else {
1091 		if( REG16(CX) == 0 )
1092 			return;
1093 	}
1094 
1095 	/* now actually perform the repeat */
1096 	CYCLES_NUM(cycle_base);
1097 	do
1098 	{
1099 		I.eip = repeated_eip;
1100 		I.pc = repeated_pc;
1101 		I386OP(decode_opcode)();
1102 		CYCLES_NUM(cycle_adjustment);
1103 
1104 		if (I.sreg[CS].d)
1105 			count = --REG32(ECX);
1106 		else
1107 			count = --REG16(CX);
1108 		if (I.cycles <= 0)
1109 			goto outofcycles;
1110 	}
1111 	while( count && (!flag || (invert_flag ? !*flag : *flag)) );
1112 	return;
1113 
1114 outofcycles:
1115 	/* if we run out of cycles to execute, and we are still in the repeat, we need
1116      * to exit this instruction in such a way to go right back into it when we have
1117      * time to execute cycles */
1118 	I.eip = I.prev_eip;
1119 	CHANGE_PC(I.eip);
1120 	CYCLES_NUM(-cycle_base);
1121 }
1122 
I386OP(rep)1123 static void I386OP(rep)(void)				// Opcode 0xf3
1124 {
1125 	I386OP(repeat)(0);
1126 	}
1127 
I386OP(repne)1128 static void I386OP(repne)(void)				// Opcode 0xf2
1129 	{
1130 	I386OP(repeat)(1);
1131 }
1132 
I386OP(sahf)1133 static void I386OP(sahf)(void)				// Opcode 0x9e
1134 {
1135 	set_flags( (get_flags() & 0xffffff00) | (REG8(AH) & 0xd7) );
1136 	CYCLES(CYCLES_SAHF);
1137 }
1138 
I386OP(sbb_rm8_r8)1139 static void I386OP(sbb_rm8_r8)(void)		// Opcode 0x18
1140 {
1141 	UINT8 src, dst;
1142 	UINT8 modrm = FETCH();
1143 	if( modrm >= 0xc0 ) {
1144 		src = LOAD_REG8(modrm) + I.CF;
1145 		dst = LOAD_RM8(modrm);
1146 		dst = SUB8(dst, src);
1147 		STORE_RM8(modrm, dst);
1148 		CYCLES(CYCLES_ALU_REG_REG);
1149 	} else {
1150 		UINT32 ea = GetEA(modrm);
1151 		src = LOAD_REG8(modrm) + I.CF;
1152 		dst = READ8(ea);
1153 		dst = SUB8(dst, src);
1154 		WRITE8(ea, dst);
1155 		CYCLES(CYCLES_ALU_REG_MEM);
1156 	}
1157 }
1158 
I386OP(sbb_r8_rm8)1159 static void I386OP(sbb_r8_rm8)(void)		// Opcode 0x1a
1160 {
1161 	UINT8 src, dst;
1162 	UINT8 modrm = FETCH();
1163 	if( modrm >= 0xc0 ) {
1164 		src = LOAD_RM8(modrm) + I.CF;
1165 		dst = LOAD_REG8(modrm);
1166 		dst = SUB8(dst, src);
1167 		STORE_REG8(modrm, dst);
1168 		CYCLES(CYCLES_ALU_REG_REG);
1169 	} else {
1170 		UINT32 ea = GetEA(modrm);
1171 		src = READ8(ea) + I.CF;
1172 		dst = LOAD_REG8(modrm);
1173 		dst = SUB8(dst, src);
1174 		STORE_REG8(modrm, dst);
1175 		CYCLES(CYCLES_ALU_MEM_REG);
1176 	}
1177 }
1178 
I386OP(sbb_al_i8)1179 static void I386OP(sbb_al_i8)(void)			// Opcode 0x1c
1180 {
1181 	UINT8 src, dst;
1182 	src = FETCH() + I.CF;
1183 	dst = REG8(AL);
1184 	dst = SUB8(dst, src);
1185 	REG8(AL) = dst;
1186 	CYCLES(CYCLES_ALU_IMM_ACC);
1187 }
1188 
I386OP(scasb)1189 static void I386OP(scasb)(void)				// Opcode 0xae
1190 {
1191 	UINT32 eas;
1192 	UINT8 src, dst;
1193 	eas = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1194 	src = READ8(eas);
1195 	dst = REG8(AL);
1196 	SUB8(dst, src);
1197 	BUMP_DI(1);
1198 	CYCLES(CYCLES_SCAS);
1199 }
1200 
I386OP(setalc)1201 static void I386OP(setalc)(void)			// Opcode 0xd6 (undocumented)
1202 {
1203 	if( I.CF ) {
1204 		REG8(AL) = 0xff;
1205 	} else {
1206 		REG8(AL) = 0;
1207 	}
1208 	CYCLES(3);
1209 }
1210 
I386OP(seta_rm8)1211 static void I386OP(seta_rm8)(void)			// Opcode 0x0f 97
1212 {
1213 	UINT8 modrm = FETCH();
1214 	UINT8 value = 0;
1215 	if( I.CF == 0 && I.ZF == 0 ) {
1216 		value = 1;
1217 	}
1218 	if( modrm >= 0xc0 ) {
1219 		STORE_RM8(modrm, value);
1220 		CYCLES(CYCLES_SETCC_REG);
1221 	} else {
1222 		UINT32 ea = GetEA(modrm);
1223 		WRITE8(ea, value);
1224 		CYCLES(CYCLES_SETCC_MEM);
1225 	}
1226 }
1227 
I386OP(setbe_rm8)1228 static void I386OP(setbe_rm8)(void)			// Opcode 0x0f 96
1229 {
1230 	UINT8 modrm = FETCH();
1231 	UINT8 value = 0;
1232 	if( I.CF != 0 || I.ZF != 0 ) {
1233 		value = 1;
1234 	}
1235 	if( modrm >= 0xc0 ) {
1236 		STORE_RM8(modrm, value);
1237 		CYCLES(CYCLES_SETCC_REG);
1238 	} else {
1239 		UINT32 ea = GetEA(modrm);
1240 		WRITE8(ea, value);
1241 		CYCLES(CYCLES_SETCC_MEM);
1242 	}
1243 }
1244 
I386OP(setc_rm8)1245 static void I386OP(setc_rm8)(void)			// Opcode 0x0f 92
1246 {
1247 	UINT8 modrm = FETCH();
1248 	UINT8 value = 0;
1249 	if( I.CF != 0 ) {
1250 		value = 1;
1251 	}
1252 	if( modrm >= 0xc0 ) {
1253 		STORE_RM8(modrm, value);
1254 		CYCLES(CYCLES_SETCC_REG);
1255 	} else {
1256 		UINT32 ea = GetEA(modrm);
1257 		WRITE8(ea, value);
1258 		CYCLES(CYCLES_SETCC_MEM);
1259 	}
1260 }
1261 
I386OP(setg_rm8)1262 static void I386OP(setg_rm8)(void)			// Opcode 0x0f 9f
1263 {
1264 	UINT8 modrm = FETCH();
1265 	UINT8 value = 0;
1266 	if( I.ZF == 0 && (I.SF == I.OF) ) {
1267 		value = 1;
1268 	}
1269 	if( modrm >= 0xc0 ) {
1270 		STORE_RM8(modrm, value);
1271 		CYCLES(CYCLES_SETCC_REG);
1272 	} else {
1273 		UINT32 ea = GetEA(modrm);
1274 		WRITE8(ea, value);
1275 		CYCLES(CYCLES_SETCC_MEM);
1276 	}
1277 }
1278 
I386OP(setge_rm8)1279 static void I386OP(setge_rm8)(void)			// Opcode 0x0f 9d
1280 {
1281 	UINT8 modrm = FETCH();
1282 	UINT8 value = 0;
1283 	if( (I.SF == I.OF) ) {
1284 		value = 1;
1285 	}
1286 	if( modrm >= 0xc0 ) {
1287 		STORE_RM8(modrm, value);
1288 		CYCLES(CYCLES_SETCC_REG);
1289 	} else {
1290 		UINT32 ea = GetEA(modrm);
1291 		WRITE8(ea, value);
1292 		CYCLES(CYCLES_SETCC_MEM);
1293 	}
1294 }
1295 
I386OP(setl_rm8)1296 static void I386OP(setl_rm8)(void)			// Opcode 0x0f 9c
1297 {
1298 	UINT8 modrm = FETCH();
1299 	UINT8 value = 0;
1300 	if( I.SF != I.OF ) {
1301 		value = 1;
1302 	}
1303 	if( modrm >= 0xc0 ) {
1304 		STORE_RM8(modrm, value);
1305 		CYCLES(CYCLES_SETCC_REG);
1306 	} else {
1307 		UINT32 ea = GetEA(modrm);
1308 		WRITE8(ea, value);
1309 		CYCLES(CYCLES_SETCC_MEM);
1310 	}
1311 }
1312 
I386OP(setle_rm8)1313 static void I386OP(setle_rm8)(void)			// Opcode 0x0f 9e
1314 {
1315 	UINT8 modrm = FETCH();
1316 	UINT8 value = 0;
1317 	if( I.ZF != 0 || (I.SF != I.OF) ) {
1318 		value = 1;
1319 	}
1320 	if( modrm >= 0xc0 ) {
1321 		STORE_RM8(modrm, value);
1322 		CYCLES(CYCLES_SETCC_REG);
1323 	} else {
1324 		UINT32 ea = GetEA(modrm);
1325 		WRITE8(ea, value);
1326 		CYCLES(CYCLES_SETCC_MEM);
1327 	}
1328 }
1329 
I386OP(setnc_rm8)1330 static void I386OP(setnc_rm8)(void)			// Opcode 0x0f 93
1331 {
1332 	UINT8 modrm = FETCH();
1333 	UINT8 value = 0;
1334 	if( I.CF == 0 ) {
1335 		value = 1;
1336 	}
1337 	if( modrm >= 0xc0 ) {
1338 		STORE_RM8(modrm, value);
1339 		CYCLES(CYCLES_SETCC_REG);
1340 	} else {
1341 		UINT32 ea = GetEA(modrm);
1342 		WRITE8(ea, value);
1343 		CYCLES(CYCLES_SETCC_MEM);
1344 	}
1345 }
1346 
I386OP(setno_rm8)1347 static void I386OP(setno_rm8)(void)			// Opcode 0x0f 91
1348 {
1349 	UINT8 modrm = FETCH();
1350 	UINT8 value = 0;
1351 	if( I.OF == 0 ) {
1352 		value = 1;
1353 	}
1354 	if( modrm >= 0xc0 ) {
1355 		STORE_RM8(modrm, value);
1356 		CYCLES(CYCLES_SETCC_REG);
1357 	} else {
1358 		UINT32 ea = GetEA(modrm);
1359 		WRITE8(ea, value);
1360 		CYCLES(CYCLES_SETCC_MEM);
1361 	}
1362 }
1363 
I386OP(setnp_rm8)1364 static void I386OP(setnp_rm8)(void)			// Opcode 0x0f 9b
1365 {
1366 	UINT8 modrm = FETCH();
1367 	UINT8 value = 0;
1368 	if( I.PF == 0 ) {
1369 		value = 1;
1370 	}
1371 	if( modrm >= 0xc0 ) {
1372 		STORE_RM8(modrm, value);
1373 		CYCLES(CYCLES_SETCC_REG);
1374 	} else {
1375 		UINT32 ea = GetEA(modrm);
1376 		WRITE8(ea, value);
1377 		CYCLES(CYCLES_SETCC_MEM);
1378 	}
1379 }
1380 
I386OP(setns_rm8)1381 static void I386OP(setns_rm8)(void)			// Opcode 0x0f 99
1382 {
1383 	UINT8 modrm = FETCH();
1384 	UINT8 value = 0;
1385 	if( I.SF == 0 ) {
1386 		value = 1;
1387 	}
1388 	if( modrm >= 0xc0 ) {
1389 		STORE_RM8(modrm, value);
1390 		CYCLES(CYCLES_SETCC_REG);
1391 	} else {
1392 		UINT32 ea = GetEA(modrm);
1393 		WRITE8(ea, value);
1394 		CYCLES(CYCLES_SETCC_MEM);
1395 	}
1396 }
1397 
I386OP(setnz_rm8)1398 static void I386OP(setnz_rm8)(void)			// Opcode 0x0f 95
1399 {
1400 	UINT8 modrm = FETCH();
1401 	UINT8 value = 0;
1402 	if( I.ZF == 0 ) {
1403 		value = 1;
1404 	}
1405 	if( modrm >= 0xc0 ) {
1406 		STORE_RM8(modrm, value);
1407 		CYCLES(CYCLES_SETCC_REG);
1408 	} else {
1409 		UINT32 ea = GetEA(modrm);
1410 		WRITE8(ea, value);
1411 		CYCLES(CYCLES_SETCC_MEM);
1412 	}
1413 }
1414 
I386OP(seto_rm8)1415 static void I386OP(seto_rm8)(void)			// Opcode 0x0f 90
1416 {
1417 	UINT8 modrm = FETCH();
1418 	UINT8 value = 0;
1419 	if( I.OF != 0 ) {
1420 		value = 1;
1421 	}
1422 	if( modrm >= 0xc0 ) {
1423 		STORE_RM8(modrm, value);
1424 		CYCLES(CYCLES_SETCC_REG);
1425 	} else {
1426 		UINT32 ea = GetEA(modrm);
1427 		WRITE8(ea, value);
1428 		CYCLES(CYCLES_SETCC_MEM);
1429 	}
1430 }
1431 
I386OP(setp_rm8)1432 static void I386OP(setp_rm8)(void)			// Opcode 0x0f 9a
1433 {
1434 	UINT8 modrm = FETCH();
1435 	UINT8 value = 0;
1436 	if( I.PF != 0 ) {
1437 		value = 1;
1438 	}
1439 	if( modrm >= 0xc0 ) {
1440 		STORE_RM8(modrm, value);
1441 		CYCLES(CYCLES_SETCC_REG);
1442 	} else {
1443 		UINT32 ea = GetEA(modrm);
1444 		WRITE8(ea, value);
1445 		CYCLES(CYCLES_SETCC_MEM);
1446 	}
1447 }
1448 
I386OP(sets_rm8)1449 static void I386OP(sets_rm8)(void)			// Opcode 0x0f 98
1450 {
1451 	UINT8 modrm = FETCH();
1452 	UINT8 value = 0;
1453 	if( I.SF != 0 ) {
1454 		value = 1;
1455 	}
1456 	if( modrm >= 0xc0 ) {
1457 		STORE_RM8(modrm, value);
1458 		CYCLES(CYCLES_SETCC_REG);
1459 	} else {
1460 		UINT32 ea = GetEA(modrm);
1461 		WRITE8(ea, value);
1462 		CYCLES(CYCLES_SETCC_MEM);
1463 	}
1464 }
1465 
I386OP(setz_rm8)1466 static void I386OP(setz_rm8)(void)			// Opcode 0x0f 94
1467 {
1468 	UINT8 modrm = FETCH();
1469 	UINT8 value = 0;
1470 	if( I.ZF != 0 ) {
1471 		value = 1;
1472 	}
1473 	if( modrm >= 0xc0 ) {
1474 		STORE_RM8(modrm, value);
1475 		CYCLES(CYCLES_SETCC_REG);
1476 	} else {
1477 		UINT32 ea = GetEA(modrm);
1478 		WRITE8(ea, value);
1479 		CYCLES(CYCLES_SETCC_MEM);
1480 	}
1481 }
1482 
I386OP(stc)1483 static void I386OP(stc)(void)				// Opcode 0xf9
1484 {
1485 	I.CF = 1;
1486 	CYCLES(CYCLES_STC);
1487 }
1488 
I386OP(std)1489 static void I386OP(std)(void)				// Opcode 0xfd
1490 {
1491 	I.DF = 1;
1492 	CYCLES(CYCLES_STD);
1493 }
1494 
I386OP(sti)1495 static void I386OP(sti)(void)				// Opcode 0xfb
1496 {
1497 	I.IF = 1;
1498 	i386_check_irq_line();
1499 	CYCLES(CYCLES_STI);
1500 }
1501 
I386OP(stosb)1502 static void I386OP(stosb)(void)				// Opcode 0xaa
1503 {
1504 	UINT32 ead;
1505 	ead = i386_translate( ES, I.address_size ? REG32(EDI) : REG16(DI) );
1506 	WRITE8(ead, REG8(AL));
1507 	BUMP_DI(1);
1508 	CYCLES(CYCLES_STOS);
1509 }
1510 
I386OP(sub_rm8_r8)1511 static void I386OP(sub_rm8_r8)(void)		// Opcode 0x28
1512 {
1513 	UINT8 src, dst;
1514 	UINT8 modrm = FETCH();
1515 	if( modrm >= 0xc0 ) {
1516 		src = LOAD_REG8(modrm);
1517 		dst = LOAD_RM8(modrm);
1518 		dst = SUB8(dst, src);
1519 		STORE_RM8(modrm, dst);
1520 		CYCLES(CYCLES_ALU_REG_REG);
1521 	} else {
1522 		UINT32 ea = GetEA(modrm);
1523 		src = LOAD_REG8(modrm);
1524 		dst = READ8(ea);
1525 		dst = SUB8(dst, src);
1526 		WRITE8(ea, dst);
1527 		CYCLES(CYCLES_ALU_REG_MEM);
1528 	}
1529 }
1530 
I386OP(sub_r8_rm8)1531 static void I386OP(sub_r8_rm8)(void)		// Opcode 0x2a
1532 {
1533 	UINT8 src, dst;
1534 	UINT8 modrm = FETCH();
1535 	if( modrm >= 0xc0 ) {
1536 		src = LOAD_RM8(modrm);
1537 		dst = LOAD_REG8(modrm);
1538 		dst = SUB8(dst, src);
1539 		STORE_REG8(modrm, dst);
1540 		CYCLES(CYCLES_ALU_REG_REG);
1541 	} else {
1542 		UINT32 ea = GetEA(modrm);
1543 		src = READ8(ea);
1544 		dst = LOAD_REG8(modrm);
1545 		dst = SUB8(dst, src);
1546 		STORE_REG8(modrm, dst);
1547 		CYCLES(CYCLES_ALU_MEM_REG);
1548 	}
1549 }
1550 
I386OP(sub_al_i8)1551 static void I386OP(sub_al_i8)(void)			// Opcode 0x2c
1552 {
1553 	UINT8 src, dst;
1554 	src = FETCH();
1555 	dst = REG8(AL);
1556 	dst = SUB8(dst, src);
1557 	REG8(AL) = dst;
1558 	CYCLES(CYCLES_ALU_IMM_ACC);
1559 }
1560 
I386OP(test_al_i8)1561 static void I386OP(test_al_i8)(void)		// Opcode 0xa8
1562 {
1563 	UINT8 src = FETCH();
1564 	UINT8 dst = REG8(AL);
1565 	dst = src & dst;
1566 	SetSZPF8(dst);
1567 	I.CF = 0;
1568 	I.OF = 0;
1569 	CYCLES(CYCLES_ALU_IMM_ACC);
1570 }
1571 
I386OP(test_rm8_r8)1572 static void I386OP(test_rm8_r8)(void)		// Opcode 0x84
1573 {
1574 	UINT8 src, dst;
1575 	UINT8 modrm = FETCH();
1576 	if( modrm >= 0xc0 ) {
1577 		src = LOAD_REG8(modrm);
1578 		dst = LOAD_RM8(modrm);
1579 		dst = src & dst;
1580 		SetSZPF8(dst);
1581 		I.CF = 0;
1582 		I.OF = 0;
1583 		CYCLES(CYCLES_TEST_REG_REG);
1584 	} else {
1585 		UINT32 ea = GetEA(modrm);
1586 		src = LOAD_REG8(modrm);
1587 		dst = READ8(ea);
1588 		dst = src & dst;
1589 		SetSZPF8(dst);
1590 		I.CF = 0;
1591 		I.OF = 0;
1592 		CYCLES(CYCLES_TEST_REG_MEM);
1593 	}
1594 }
1595 
I386OP(xchg_r8_rm8)1596 static void I386OP(xchg_r8_rm8)(void)		// Opcode 0x86
1597 {
1598 	UINT8 modrm = FETCH();
1599 	if( modrm >= 0xc0 ) {
1600 		UINT8 src = LOAD_RM8(modrm);
1601 		UINT8 dst = LOAD_REG8(modrm);
1602 		STORE_REG8(modrm, src);
1603 		STORE_RM8(modrm, dst);
1604 		CYCLES(CYCLES_XCHG_REG_REG);
1605 	} else {
1606 		UINT32 ea = GetEA(modrm);
1607 		UINT8 src = READ8(ea);
1608 		UINT8 dst = LOAD_REG8(modrm);
1609 		STORE_REG8(modrm, src);
1610 		WRITE8(ea, dst);
1611 		CYCLES(CYCLES_XCHG_REG_MEM);
1612 	}
1613 }
1614 
I386OP(xor_rm8_r8)1615 static void I386OP(xor_rm8_r8)(void)		// Opcode 0x30
1616 {
1617 	UINT8 src, dst;
1618 	UINT8 modrm = FETCH();
1619 	if( modrm >= 0xc0 ) {
1620 		src = LOAD_REG8(modrm);
1621 		dst = LOAD_RM8(modrm);
1622 		dst = XOR8(dst, src);
1623 		STORE_RM8(modrm, dst);
1624 		CYCLES(CYCLES_ALU_REG_REG);
1625 	} else {
1626 		UINT32 ea = GetEA(modrm);
1627 		src = LOAD_REG8(modrm);
1628 		dst = READ8(ea);
1629 		dst = XOR8(dst, src);
1630 		WRITE8(ea, dst);
1631 		CYCLES(CYCLES_ALU_REG_MEM);
1632 	}
1633 }
1634 
I386OP(xor_r8_rm8)1635 static void I386OP(xor_r8_rm8)(void)		// Opcode 0x32
1636 {
1637 	UINT32 src, dst;
1638 	UINT8 modrm = FETCH();
1639 	if( modrm >= 0xc0 ) {
1640 		src = LOAD_RM8(modrm);
1641 		dst = LOAD_REG8(modrm);
1642 		dst = XOR8(dst, src);
1643 		STORE_REG8(modrm, dst);
1644 		CYCLES(CYCLES_ALU_REG_REG);
1645 	} else {
1646 		UINT32 ea = GetEA(modrm);
1647 		src = READ8(ea);
1648 		dst = LOAD_REG8(modrm);
1649 		dst = XOR8(dst, src);
1650 		STORE_REG8(modrm, dst);
1651 		CYCLES(CYCLES_ALU_MEM_REG);
1652 	}
1653 }
1654 
I386OP(xor_al_i8)1655 static void I386OP(xor_al_i8)(void)			// Opcode 0x34
1656 {
1657 	UINT8 src, dst;
1658 	src = FETCH();
1659 	dst = REG8(AL);
1660 	dst = XOR8(dst, src);
1661 	REG8(AL) = dst;
1662 	CYCLES(CYCLES_ALU_IMM_ACC);
1663 }
1664 
1665 
1666 
I386OP(group80_8)1667 static void I386OP(group80_8)(void)			// Opcode 0x80
1668 {
1669 	UINT32 ea;
1670 	UINT8 src, dst;
1671 	UINT8 modrm = FETCH();
1672 
1673 	switch( (modrm >> 3) & 0x7 )
1674 	{
1675 		case 0:		// ADD Rm8, i8
1676 			if( modrm >= 0xc0 ) {
1677 				dst = LOAD_RM8(modrm);
1678 				src = FETCH();
1679 				dst = ADD8(dst, src);
1680 				STORE_RM8(modrm, dst);
1681 				CYCLES(CYCLES_ALU_REG_REG);
1682 			} else {
1683 				ea = GetEA(modrm);
1684 				dst = READ8(ea);
1685 				src = FETCH();
1686 				dst = ADD8(dst, src);
1687 				WRITE8(ea, dst);
1688 				CYCLES(CYCLES_ALU_REG_MEM);
1689 			}
1690 			break;
1691 		case 1:		// OR Rm8, i8
1692 			if( modrm >= 0xc0 ) {
1693 				dst = LOAD_RM8(modrm);
1694 				src = FETCH();
1695 				dst = OR8(dst, src);
1696 				STORE_RM8(modrm, dst);
1697 				CYCLES(CYCLES_ALU_REG_REG);
1698 			} else {
1699 				ea = GetEA(modrm);
1700 				dst = READ8(ea);
1701 				src = FETCH();
1702 				dst = OR8(dst, src);
1703 				WRITE8(ea, dst);
1704 				CYCLES(CYCLES_ALU_REG_MEM);
1705 			}
1706 			break;
1707 		case 2:		// ADC Rm8, i8
1708 			if( modrm >= 0xc0 ) {
1709 				dst = LOAD_RM8(modrm);
1710 				src = FETCH();
1711 				src = ADD8(src, I.CF);
1712 				dst = ADD8(dst, src);
1713 				STORE_RM8(modrm, dst);
1714 				CYCLES(CYCLES_ALU_REG_REG);
1715 			} else {
1716 				ea = GetEA(modrm);
1717 				dst = READ8(ea);
1718 				src = FETCH();
1719 				src = ADD8(src, I.CF);
1720 				dst = ADD8(dst, src);
1721 				WRITE8(ea, dst);
1722 				CYCLES(CYCLES_ALU_REG_MEM);
1723 			}
1724 			break;
1725 		case 3:		// SBB Rm8, i8
1726 			if( modrm >= 0xc0 ) {
1727 				dst = LOAD_RM8(modrm);
1728 				src = FETCH() + I.CF;
1729 				dst = SUB8(dst, src);
1730 				STORE_RM8(modrm, dst);
1731 				CYCLES(CYCLES_ALU_REG_REG);
1732 			} else {
1733 				ea = GetEA(modrm);
1734 				dst = READ8(ea);
1735 				src = FETCH() + I.CF;
1736 				dst = SUB8(dst, src);
1737 				WRITE8(ea, dst);
1738 				CYCLES(CYCLES_ALU_REG_MEM);
1739 			}
1740 			break;
1741 		case 4:		// AND Rm8, i8
1742 			if( modrm >= 0xc0 ) {
1743 				dst = LOAD_RM8(modrm);
1744 				src = FETCH();
1745 				dst = AND8(dst, src);
1746 				STORE_RM8(modrm, dst);
1747 				CYCLES(CYCLES_ALU_REG_REG);
1748 			} else {
1749 				ea = GetEA(modrm);
1750 				dst = READ8(ea);
1751 				src = FETCH();
1752 				dst = AND8(dst, src);
1753 				WRITE8(ea, dst);
1754 				CYCLES(CYCLES_ALU_REG_MEM);
1755 			}
1756 			break;
1757 		case 5:		// SUB Rm8, i8
1758 			if( modrm >= 0xc0 ) {
1759 				dst = LOAD_RM8(modrm);
1760 				src = FETCH();
1761 				dst = SUB8(dst, src);
1762 				STORE_RM8(modrm, dst);
1763 				CYCLES(CYCLES_ALU_REG_REG);
1764 			} else {
1765 				ea = GetEA(modrm);
1766 				dst = READ8(ea);
1767 				src = FETCH();
1768 				dst = SUB8(dst, src);
1769 				WRITE8(ea, dst);
1770 				CYCLES(CYCLES_ALU_REG_MEM);
1771 			}
1772 			break;
1773 		case 6:		// XOR Rm8, i8
1774 			if( modrm >= 0xc0 ) {
1775 				dst = LOAD_RM8(modrm);
1776 				src = FETCH();
1777 				dst = XOR8(dst, src);
1778 				STORE_RM8(modrm, dst);
1779 				CYCLES(CYCLES_ALU_REG_REG);
1780 			} else {
1781 				ea = GetEA(modrm);
1782 				dst = READ8(ea);
1783 				src = FETCH();
1784 				dst = XOR8(dst, src);
1785 				WRITE8(ea, dst);
1786 				CYCLES(CYCLES_ALU_REG_MEM);
1787 			}
1788 			break;
1789 		case 7:		// CMP Rm8, i8
1790 			if( modrm >= 0xc0 ) {
1791 				dst = LOAD_RM8(modrm);
1792 				src = FETCH();
1793 				SUB8(dst, src);
1794 				CYCLES(CYCLES_CMP_REG_REG);
1795 			} else {
1796 				ea = GetEA(modrm);
1797 				dst = READ8(ea);
1798 				src = FETCH();
1799 				SUB8(dst, src);
1800 				CYCLES(CYCLES_CMP_REG_MEM);
1801 			}
1802 			break;
1803 	}
1804 }
1805 
I386OP(groupC0_8)1806 static void I386OP(groupC0_8)(void)			// Opcode 0xc0
1807 {
1808 	UINT8 dst;
1809 	UINT8 modrm = FETCH();
1810 	UINT8 shift;
1811 
1812 	if( modrm >= 0xc0 ) {
1813 		dst = LOAD_RM8(modrm);
1814 		shift = FETCH() & 0x1f;
1815 		dst = i386_shift_rotate8(modrm, dst, shift);
1816 		STORE_RM8(modrm, dst);
1817 	} else {
1818 		UINT32 ea = GetEA(modrm);
1819 		dst = READ8(ea);
1820 		shift = FETCH() & 0x1f;
1821 		dst = i386_shift_rotate8(modrm, dst, shift);
1822 		WRITE8(ea, dst);
1823 	}
1824 }
1825 
I386OP(groupD0_8)1826 static void I386OP(groupD0_8)(void)			// Opcode 0xd0
1827 {
1828 	UINT8 dst;
1829 	UINT8 modrm = FETCH();
1830 
1831 	if( modrm >= 0xc0 ) {
1832 		dst = LOAD_RM8(modrm);
1833 		dst = i386_shift_rotate8(modrm, dst, 1);
1834 		STORE_RM8(modrm, dst);
1835 	} else {
1836 		UINT32 ea = GetEA(modrm);
1837 		dst = READ8(ea);
1838 		dst = i386_shift_rotate8(modrm, dst, 1);
1839 		WRITE8(ea, dst);
1840 	}
1841 }
1842 
I386OP(groupD2_8)1843 static void I386OP(groupD2_8)(void)			// Opcode 0xd2
1844 {
1845 	UINT8 dst;
1846 	UINT8 modrm = FETCH();
1847 
1848 	if( modrm >= 0xc0 ) {
1849 		dst = LOAD_RM8(modrm);
1850 		dst = i386_shift_rotate8(modrm, dst, REG8(CL));
1851 		STORE_RM8(modrm, dst);
1852 	} else {
1853 		UINT32 ea = GetEA(modrm);
1854 		dst = READ8(ea);
1855 		dst = i386_shift_rotate8(modrm, dst, REG8(CL));
1856 		WRITE8(ea, dst);
1857 	}
1858 }
1859 
I386OP(groupF6_8)1860 static void I386OP(groupF6_8)(void)			// Opcode 0xf6
1861 {
1862 	UINT8 modrm = FETCH();
1863 
1864 	switch( (modrm >> 3) & 0x7 )
1865 	{
1866 		case 0:			/* TEST Rm8, i8 */
1867 			if( modrm >= 0xc0 ) {
1868 				UINT8 dst = LOAD_RM8(modrm);
1869 				UINT8 src = FETCH();
1870 				dst &= src;
1871 				I.CF = I.OF = I.AF = 0;
1872 				SetSZPF8(dst);
1873 				CYCLES(CYCLES_TEST_IMM_REG);
1874 			} else {
1875 				UINT32 ea = GetEA(modrm);
1876 				UINT8 dst = READ8(ea);
1877 				UINT8 src = FETCH();
1878 				dst &= src;
1879 				I.CF = I.OF = I.AF = 0;
1880 				SetSZPF8(dst);
1881 				CYCLES(CYCLES_TEST_IMM_MEM);
1882 			}
1883 			break;
1884 		case 2:			/* NOT Rm8 */
1885 			if( modrm >= 0xc0 ) {
1886 				UINT8 dst = LOAD_RM8(modrm);
1887 				dst = ~dst;
1888 				STORE_RM8(modrm, dst);
1889 				CYCLES(CYCLES_NOT_REG);
1890 			} else {
1891 				UINT32 ea = GetEA(modrm);
1892 				UINT8 dst = READ8(ea);
1893 				dst = ~dst;
1894 				WRITE8(ea, dst);
1895 				CYCLES(CYCLES_NOT_MEM);
1896 			}
1897 			break;
1898 		case 3:			/* NEG Rm8 */
1899 			if( modrm >= 0xc0 ) {
1900 				UINT8 dst = LOAD_RM8(modrm);
1901 				dst = SUB8( 0, dst );
1902 				STORE_RM8(modrm, dst);
1903 				CYCLES(CYCLES_NEG_REG);
1904 			} else {
1905 				UINT32 ea = GetEA(modrm);
1906 				UINT8 dst = READ8(ea);
1907 				dst = SUB8( 0, dst );
1908 				WRITE8(ea, dst);
1909 				CYCLES(CYCLES_NEG_MEM);
1910 			}
1911 			break;
1912 		case 4:			/* MUL AL, Rm8 */
1913 			{
1914 				UINT16 result;
1915 				UINT8 src, dst;
1916 				if( modrm >= 0xc0 ) {
1917 					src = LOAD_RM8(modrm);
1918 					CYCLES(CYCLES_MUL8_ACC_REG);		/* TODO: Correct multiply timing */
1919 				} else {
1920 					UINT32 ea = GetEA(modrm);
1921 					src = READ8(ea);
1922 					CYCLES(CYCLES_MUL8_ACC_MEM);		/* TODO: Correct multiply timing */
1923 				}
1924 
1925 				dst = REG8(AL);
1926 				result = (UINT16)src * (UINT16)dst;
1927 				REG16(AX) = (UINT16)result;
1928 
1929 				I.CF = I.OF = (REG16(AX) > 0xff);
1930 			}
1931 			break;
1932 		case 5:			/* IMUL AL, Rm8 */
1933 			{
1934 				INT16 result;
1935 				INT16 src, dst;
1936 				if( modrm >= 0xc0 ) {
1937 					src = (INT16)(INT8)LOAD_RM8(modrm);
1938 					CYCLES(CYCLES_IMUL8_ACC_REG);		/* TODO: Correct multiply timing */
1939 				} else {
1940 					UINT32 ea = GetEA(modrm);
1941 					src = (INT16)(INT8)READ8(ea);
1942 					CYCLES(CYCLES_IMUL8_ACC_MEM);		/* TODO: Correct multiply timing */
1943 				}
1944 
1945 				dst = (INT16)(INT8)REG8(AL);
1946 				result = src * dst;
1947 
1948 				REG16(AX) = (UINT16)result;
1949 
1950 				I.CF = I.OF = !(result == (INT16)(INT8)result);
1951 			}
1952 			break;
1953 		case 6:			/* DIV AL, Rm8 */
1954 			{
1955 				UINT16 quotient, remainder, result;
1956 				UINT8 src;
1957 				if( modrm >= 0xc0 ) {
1958 					src = LOAD_RM8(modrm);
1959 					CYCLES(CYCLES_DIV8_ACC_REG);
1960 				} else {
1961 					UINT32 ea = GetEA(modrm);
1962 					src = READ8(ea);
1963 					CYCLES(CYCLES_DIV8_ACC_MEM);
1964 				}
1965 
1966 				quotient = (UINT16)REG16(AX);
1967 				if( src ) {
1968 					remainder = quotient % (UINT16)src;
1969 					result = quotient / (UINT16)src;
1970 					if( result > 0xff ) {
1971 						/* TODO: Divide error */
1972 					} else {
1973 						REG8(AH) = (UINT8)remainder & 0xff;
1974 						REG8(AL) = (UINT8)result & 0xff;
1975 					}
1976 				} else {
1977 					/* TODO: Divide by zero */
1978 				}
1979 			}
1980 			break;
1981 		case 7:			/* IDIV AL, Rm8 */
1982 			{
1983 				INT16 quotient, remainder, result;
1984 				UINT8 src;
1985 				if( modrm >= 0xc0 ) {
1986 					src = LOAD_RM8(modrm);
1987 					CYCLES(CYCLES_IDIV8_ACC_REG);
1988 				} else {
1989 					UINT32 ea = GetEA(modrm);
1990 					src = READ8(ea);
1991 					CYCLES(CYCLES_IDIV8_ACC_MEM);
1992 				}
1993 
1994 				quotient = (INT16)REG16(AX);
1995 				if( src ) {
1996 					remainder = quotient % (INT16)(INT8)src;
1997 					result = quotient / (INT16)(INT8)src;
1998 					if( result > 0xff ) {
1999 						/* TODO: Divide error */
2000 					} else {
2001 						REG8(AH) = (UINT8)remainder & 0xff;
2002 						REG8(AL) = (UINT8)result & 0xff;
2003 					}
2004 				} else {
2005 					/* TODO: Divide by zero */
2006 				}
2007 			}
2008 			break;
2009 	}
2010 }
2011 
I386OP(groupFE_8)2012 static void I386OP(groupFE_8)(void)			// Opcode 0xfe
2013 {
2014 	UINT8 modrm = FETCH();
2015 
2016 	switch( (modrm >> 3) & 0x7 )
2017 	{
2018 		case 0:			/* INC Rm8 */
2019 			if( modrm >= 0xc0 ) {
2020 				UINT8 dst = LOAD_RM8(modrm);
2021 				dst = INC8(dst);
2022 				STORE_RM8(modrm, dst);
2023 				CYCLES(CYCLES_INC_REG);
2024 			} else {
2025 				UINT32 ea = GetEA(modrm);
2026 				UINT8 dst = READ8(ea);
2027 				dst = INC8(dst);
2028 				WRITE8(ea, dst);
2029 				CYCLES(CYCLES_INC_MEM);
2030 			}
2031 			break;
2032 		case 1:			/* DEC Rm8 */
2033 			if( modrm >= 0xc0 ) {
2034 				UINT8 dst = LOAD_RM8(modrm);
2035 				dst = DEC8(dst);
2036 				STORE_RM8(modrm, dst);
2037 				CYCLES(CYCLES_DEC_REG);
2038 			} else {
2039 				UINT32 ea = GetEA(modrm);
2040 				UINT8 dst = READ8(ea);
2041 				dst = DEC8(dst);
2042 				WRITE8(ea, dst);
2043 				CYCLES(CYCLES_DEC_MEM);
2044 			}
2045 			break;
2046 		case 6:			/* PUSH Rm8 */
2047 			{
2048 				UINT8 value;
2049 				if( modrm >= 0xc0 ) {
2050 					value = LOAD_RM8(modrm);
2051 				} else {
2052 					UINT32 ea = GetEA(modrm);
2053 					value = READ8(ea);
2054 				}
2055 				if( I.operand_size ) {
2056 					PUSH32(value);
2057 				} else {
2058 					PUSH16(value);
2059 				}
2060 				CYCLES(CYCLES_PUSH_RM);
2061 			}
2062 			break;
2063 		default:
2064 		//	osd_die("i386: groupFE_8 /%d unimplemented\n", (modrm >> 3) & 0x7);
2065 			break;
2066 	}
2067 }
2068 
2069 
2070 
I386OP(segment_CS)2071 static void I386OP(segment_CS)(void)		// Opcode 0x2e
2072 {
2073 	I.segment_prefix = 1;
2074 	I.segment_override = CS;
2075 
2076 	I386OP(decode_opcode)();
2077 }
2078 
I386OP(segment_DS)2079 static void I386OP(segment_DS)(void)		// Opcode 0x3e
2080 {
2081 	I.segment_prefix = 1;
2082 	I.segment_override = DS;
2083 	CYCLES(0);	// TODO: Specify cycle count
2084 	I386OP(decode_opcode)();
2085 }
2086 
I386OP(segment_ES)2087 static void I386OP(segment_ES)(void)		// Opcode 0x26
2088 {
2089 	I.segment_prefix = 1;
2090 	I.segment_override = ES;
2091 	CYCLES(0);	// TODO: Specify cycle count
2092 	I386OP(decode_opcode)();
2093 }
2094 
I386OP(segment_FS)2095 static void I386OP(segment_FS)(void)		// Opcode 0x64
2096 {
2097 	I.segment_prefix = 1;
2098 	I.segment_override = FS;
2099 	CYCLES(1);	// TODO: Specify cycle count
2100 	I386OP(decode_opcode)();
2101 }
2102 
I386OP(segment_GS)2103 static void I386OP(segment_GS)(void)		// Opcode 0x65
2104 {
2105 	I.segment_prefix = 1;
2106 	I.segment_override = GS;
2107 	CYCLES(1);	// TODO: Specify cycle count
2108 	I386OP(decode_opcode)();
2109 }
2110 
I386OP(segment_SS)2111 static void I386OP(segment_SS)(void)		// Opcode 0x36
2112 {
2113 	I.segment_prefix = 1;
2114 	I.segment_override = SS;
2115 	CYCLES(0);	// TODO: Specify cycle count
2116 	I386OP(decode_opcode)();
2117 }
2118 
I386OP(operand_size)2119 static void I386OP(operand_size)(void)		// Opcode 0x66
2120 {
2121 	I.operand_size ^= 1;
2122 	I386OP(decode_opcode)();
2123 }
2124 
I386OP(address_size)2125 static void I386OP(address_size)(void)		// Opcode 0x67
2126 {
2127 	I.address_size ^= 1;
2128 	I386OP(decode_opcode)();
2129 }
2130 
I386OP(nop)2131 static void I386OP(nop)(void)				// Opcode 0x90
2132 {
2133 	CYCLES(CYCLES_NOP);
2134 }
2135 
I386OP(int3)2136 static void I386OP(int3)(void)				// Opcode 0xcc
2137 {
2138 	CYCLES(CYCLES_INT3);
2139 	i386_trap(3, 1);
2140 }
2141 
I386OP(int)2142 static void I386OP(int)(void)				// Opcode 0xcd
2143 {
2144 	int interrupt = FETCH();
2145 	CYCLES(CYCLES_INT);
2146 	i386_trap(interrupt, 1);
2147 }
2148 
I386OP(into)2149 static void I386OP(into)(void)				// Opcode 0xce
2150 {
2151 	if( I.OF ) {
2152 		i386_trap(4, 1);
2153 		CYCLES(CYCLES_INTO_OF1);
2154 	}
2155 	else
2156 	{
2157 		CYCLES(CYCLES_INTO_OF0);
2158 	}
2159 }
2160 
I386OP(escape)2161 static void I386OP(escape)(void)			// Opcodes 0xd8 - 0xdf
2162 {
2163 	UINT8 modrm = FETCH();
2164 	CYCLES(3);	// TODO: confirm this
2165 	(void) LOAD_RM8(modrm);
2166 }
2167 
I386OP(hlt)2168 static void I386OP(hlt)(void)				// Opcode 0xf4
2169 {
2170 	// TODO: We need to raise an exception in protected mode and when
2171 	// the current privilege level is not zero
2172 	I.halted = 1;
2173 	I.cycles = 0;
2174 	CYCLES(CYCLES_HLT);
2175 }
2176 
I386OP(decimal_adjust)2177 static void I386OP(decimal_adjust)(int direction)
2178 {
2179 	UINT8 tmpAL = REG8(AL);
2180 
2181 	if (I.AF || ((REG8(AL) & 0xf) > 9))
2182 	{
2183 		REG8(AL) = REG8(AL) + (direction * 0x06);
2184 		I.AF = 1;
2185 		if (REG8(AL) & 0x100)
2186 			I.CF = 1;
2187 		if (direction > 0)
2188 			tmpAL = REG8(AL);
2189 	}
2190 
2191 	if (I.CF || (tmpAL > 0x9f))
2192 	{
2193 		REG8(AL) += (direction * 0x60);
2194 		I.CF = 1;
2195 	}
2196 
2197 	SetSZPF8(REG8(AL));
2198 }
2199 
I386OP(daa)2200 static void I386OP(daa)(void)				// Opcode 0x27
2201 {
2202 	I386OP(decimal_adjust)(+1);
2203 	CYCLES(CYCLES_DAA);
2204 }
2205 
I386OP(das)2206 static void I386OP(das)(void)				// Opcode 0x2f
2207 {
2208 	I386OP(decimal_adjust)(-1);
2209 	CYCLES(CYCLES_DAS);
2210 }
2211 
I386OP(aaa)2212 static void I386OP(aaa)(void)				// Opcode 0x37
2213 {
2214 	if( (REG8(AL) & 0x0f) || I.AF != 0 ) {
2215 		REG16(AX) = REG16(AX) + 6;
2216 		REG8(AH) = REG8(AH) + 1;
2217 		I.AF = 1;
2218 		I.CF = 1;
2219 	} else {
2220 		I.AF = 0;
2221 		I.CF = 0;
2222 	}
2223 	REG8(AL) = REG8(AL) & 0x0f;
2224 	CYCLES(CYCLES_AAA);
2225 }
2226 
I386OP(aas)2227 static void I386OP(aas)(void)				// Opcode 0x3f
2228 {
2229 	if (I.AF || ((REG8(AL) & 0xf) > 9))
2230     {
2231 		REG16(AX) -= 6;
2232 		REG8(AH) -= 1;
2233 		I.AF = 1;
2234 		I.CF = 1;
2235     }
2236 	else
2237 	{
2238 		I.AF = 0;
2239 		I.CF = 0;
2240     }
2241 	REG8(AL) &= 0x0f;
2242 	CYCLES(CYCLES_AAS);
2243 }
2244 
I386OP(aad)2245 static void I386OP(aad)(void)				// Opcode 0xd5
2246 {
2247 	UINT8 tempAL = REG8(AL);
2248 	UINT8 tempAH = REG8(AH);
2249 	UINT8 i = FETCH();
2250 
2251 	REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
2252 	REG8(AH) = 0;
2253 	SetSZPF8( REG8(AL) );
2254 	CYCLES(CYCLES_AAD);
2255 }
2256 
I386OP(aam)2257 static void I386OP(aam)(void)				// Opcode 0xd4
2258 {
2259 	UINT8 tempAL = REG8(AL);
2260 	UINT8 i = FETCH();
2261 
2262 	REG8(AH) = tempAL / i;
2263 	REG8(AL) = tempAL % i;
2264 	SetSZPF8( REG8(AL) );
2265 	CYCLES(CYCLES_AAM);
2266 }
2267 
I386OP(clts)2268 static void I386OP(clts)(void)				// Opcode 0x0f 0x06
2269 {
2270 	// TODO: #GP(0) is executed
2271 	I.cr[0] &= ~0x08;	/* clear TS bit */
2272 	CYCLES(CYCLES_CLTS);
2273 }
2274 
I386OP(wait)2275 static void I386OP(wait)(void)				// Opcode 0x9B
2276 {
2277 	// TODO
2278 }
2279 
I386OP(lock)2280 static void I386OP(lock)(void)				// Opcode 0xf0
2281 {
2282 	CYCLES(CYCLES_LOCK);		// TODO: Determine correct cycle count
2283 	I386OP(decode_opcode)();
2284 }
2285 
I386OP(mov_r32_tr)2286 static void I386OP(mov_r32_tr)(void)		// Opcode 0x0f 24
2287 {
2288 	FETCH();
2289 	CYCLES(1);		// TODO: correct cycle count
2290 }
2291 
I386OP(mov_tr_r32)2292 static void I386OP(mov_tr_r32)(void)		// Opcode 0x0f 26
2293 {
2294 	FETCH();
2295 	CYCLES(1);		// TODO: correct cycle count
2296 }
2297 
I386OP(unimplemented)2298 static void I386OP(unimplemented)(void)
2299 {
2300 //	osd_die("i386: Unimplemented opcode %02X at %08X\n", I.opcode, I.pc - 1 );
2301 }
2302 
I386OP(invalid)2303 static void I386OP(invalid)(void)
2304 {
2305 	//i386_trap(6);
2306 //	osd_die("i386: Invalid opcode %02X at %08X\n", I.opcode, I.pc - 1);
2307 }
2308