1 // license:BSD-3-Clause
2 // copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett
i386_shift_rotate16(uint8_t modrm,uint32_t value,uint8_t shift)3 uint16_t i386_device::i386_shift_rotate16(uint8_t modrm, uint32_t value, uint8_t shift)
4 {
5 	uint32_t src = value & 0xffff;
6 	uint16_t dst = value;
7 
8 	if( shift == 0 ) {
9 		CYCLES_RM(modrm, 3, 7);
10 	} else if( shift == 1 ) {
11 		switch( (modrm >> 3) & 0x7 )
12 		{
13 			case 0:         /* ROL rm16, 1 */
14 				m_CF = (src & 0x8000) ? 1 : 0;
15 				dst = (src << 1) + m_CF;
16 				m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
17 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
18 				break;
19 			case 1:         /* ROR rm16, 1 */
20 				m_CF = (src & 0x1) ? 1 : 0;
21 				dst = (m_CF << 15) | (src >> 1);
22 				m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
23 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
24 				break;
25 			case 2:         /* RCL rm16, 1 */
26 				dst = (src << 1) + m_CF;
27 				m_CF = (src & 0x8000) ? 1 : 0;
28 				m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
29 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
30 				break;
31 			case 3:         /* RCR rm16, 1 */
32 				dst = (m_CF << 15) | (src >> 1);
33 				m_CF = src & 0x1;
34 				m_OF = ((src ^ dst) & 0x8000) ? 1 : 0;
35 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
36 				break;
37 			case 4:         /* SHL/SAL rm16, 1 */
38 			case 6:
39 				dst = src << 1;
40 				m_CF = (src & 0x8000) ? 1 : 0;
41 				m_OF = (((m_CF << 15) ^ dst) & 0x8000) ? 1 : 0;
42 				SetSZPF16(dst);
43 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
44 				break;
45 			case 5:         /* SHR rm16, 1 */
46 				dst = src >> 1;
47 				m_CF = src & 0x1;
48 				m_OF = (dst & 0x8000) ? 1 : 0;
49 				SetSZPF16(dst);
50 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
51 				break;
52 			case 7:         /* SAR rm16, 1 */
53 				dst = (int16_t)(src) >> 1;
54 				m_CF = src & 0x1;
55 				m_OF = 0;
56 				SetSZPF16(dst);
57 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
58 				break;
59 		}
60 	} else {
61 		switch( (modrm >> 3) & 0x7 )
62 		{
63 			case 0:         /* ROL rm16, i8 */
64 				if(!(shift & 15))
65 				{
66 					if(shift & 16)
67 					{
68 						m_CF = src & 1;
69 						m_OF = (src & 1) ^ ((src >> 15) & 1);
70 					}
71 					break;
72 				}
73 				shift &= 15;
74 				dst = ((src & ((uint16_t)0xffff >> shift)) << shift) |
75 						((src & ((uint16_t)0xffff << (16-shift))) >> (16-shift));
76 				m_CF = dst & 0x1;
77 				m_OF = (dst & 1) ^ (dst >> 15);
78 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
79 				break;
80 			case 1:         /* ROR rm16, i8 */
81 				if(!(shift & 15))
82 				{
83 					if(shift & 16)
84 					{
85 						m_CF = (src >> 15) & 1;
86 						m_OF = ((src >> 15) & 1) ^ ((src >> 14) & 1);
87 					}
88 					break;
89 				}
90 				shift &= 15;
91 				dst = ((src & ((uint16_t)0xffff << shift)) >> shift) |
92 						((src & ((uint16_t)0xffff >> (16-shift))) << (16-shift));
93 				m_CF = (dst >> 15) & 1;
94 				m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
95 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
96 				break;
97 			case 2:         /* RCL rm16, i8 */
98 				shift %= 17;
99 				dst = ((src & ((uint16_t)0xffff >> shift)) << shift) |
100 						((src & ((uint16_t)0xffff << (17-shift))) >> (17-shift)) |
101 						(m_CF << (shift-1));
102 				if(shift) m_CF = (src >> (16-shift)) & 0x1;
103 				m_OF = m_CF ^ ((dst >> 15) & 1);
104 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
105 				break;
106 			case 3:         /* RCR rm16, i8 */
107 				shift %= 17;
108 				dst = ((src & ((uint16_t)0xffff << shift)) >> shift) |
109 						((src & ((uint16_t)0xffff >> (16-shift))) << (17-shift)) |
110 						(m_CF << (16-shift));
111 				if(shift) m_CF = (src >> (shift-1)) & 0x1;
112 				m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
113 				CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
114 				break;
115 			case 4:         /* SHL/SAL rm16, i8 */
116 			case 6:
117 				shift &= 31;
118 				dst = src << shift;
119 				m_CF = (shift <= 16) && (src & (1 << (16-shift)));
120 				SetSZPF16(dst);
121 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
122 				break;
123 			case 5:         /* SHR rm16, i8 */
124 				shift &= 31;
125 				dst = src >> shift;
126 				m_CF = (src & (1 << (shift-1))) ? 1 : 0;
127 				SetSZPF16(dst);
128 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
129 				break;
130 			case 7:         /* SAR rm16, i8 */
131 				shift &= 31;
132 				dst = (int16_t)src >> shift;
133 				m_CF = (src & (1 << (shift-1))) ? 1 : 0;
134 				SetSZPF16(dst);
135 				CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
136 				break;
137 		}
138 
139 	}
140 	return dst;
141 }
142 
143 
144 
i386_adc_rm16_r16()145 void i386_device::i386_adc_rm16_r16()      // Opcode 0x11
146 {
147 	uint16_t src, dst;
148 	uint8_t modrm = FETCH();
149 	if( modrm >= 0xc0 ) {
150 		src = LOAD_REG16(modrm);
151 		dst = LOAD_RM16(modrm);
152 		dst = ADC16(dst, src, m_CF);
153 		STORE_RM16(modrm, dst);
154 		CYCLES(CYCLES_ALU_REG_REG);
155 	} else {
156 		uint32_t ea = GetEA(modrm,1);
157 		src = LOAD_REG16(modrm);
158 		dst = READ16(ea);
159 		dst = ADC16(dst, src, m_CF);
160 		WRITE16(ea, dst);
161 		CYCLES(CYCLES_ALU_REG_MEM);
162 	}
163 }
164 
i386_adc_r16_rm16()165 void i386_device::i386_adc_r16_rm16()      // Opcode 0x13
166 {
167 	uint16_t src, dst;
168 	uint8_t modrm = FETCH();
169 	if( modrm >= 0xc0 ) {
170 		src = LOAD_RM16(modrm);
171 		dst = LOAD_REG16(modrm);
172 		dst = ADC16(dst, src, m_CF);
173 		STORE_REG16(modrm, dst);
174 		CYCLES(CYCLES_ALU_REG_REG);
175 	} else {
176 		uint32_t ea = GetEA(modrm,0);
177 		src = READ16(ea);
178 		dst = LOAD_REG16(modrm);
179 		dst = ADC16(dst, src, m_CF);
180 		STORE_REG16(modrm, dst);
181 		CYCLES(CYCLES_ALU_MEM_REG);
182 	}
183 }
184 
i386_adc_ax_i16()185 void i386_device::i386_adc_ax_i16()        // Opcode 0x15
186 {
187 	uint16_t src, dst;
188 	src = FETCH16();
189 	dst = REG16(AX);
190 	dst = ADC16(dst, src, m_CF);
191 	REG16(AX) = dst;
192 	CYCLES(CYCLES_ALU_IMM_ACC);
193 }
194 
i386_add_rm16_r16()195 void i386_device::i386_add_rm16_r16()      // Opcode 0x01
196 {
197 	uint16_t src, dst;
198 	uint8_t modrm = FETCH();
199 	if( modrm >= 0xc0 ) {
200 		src = LOAD_REG16(modrm);
201 		dst = LOAD_RM16(modrm);
202 		dst = ADD16(dst, src);
203 		STORE_RM16(modrm, dst);
204 		CYCLES(CYCLES_ALU_REG_REG);
205 	} else {
206 		uint32_t ea = GetEA(modrm,1);
207 		src = LOAD_REG16(modrm);
208 		dst = READ16(ea);
209 		dst = ADD16(dst, src);
210 		WRITE16(ea, dst);
211 		CYCLES(CYCLES_ALU_REG_MEM);
212 	}
213 }
214 
i386_add_r16_rm16()215 void i386_device::i386_add_r16_rm16()      // Opcode 0x03
216 {
217 	uint16_t src, dst;
218 	uint8_t modrm = FETCH();
219 	if( modrm >= 0xc0 ) {
220 		src = LOAD_RM16(modrm);
221 		dst = LOAD_REG16(modrm);
222 		dst = ADD16(dst, src);
223 		STORE_REG16(modrm, dst);
224 		CYCLES(CYCLES_ALU_REG_REG);
225 	} else {
226 		uint32_t ea = GetEA(modrm,0);
227 		src = READ16(ea);
228 		dst = LOAD_REG16(modrm);
229 		dst = ADD16(dst, src);
230 		STORE_REG16(modrm, dst);
231 		CYCLES(CYCLES_ALU_MEM_REG);
232 	}
233 }
234 
i386_add_ax_i16()235 void i386_device::i386_add_ax_i16()        // Opcode 0x05
236 {
237 	uint16_t src, dst;
238 	src = FETCH16();
239 	dst = REG16(AX);
240 	dst = ADD16(dst, src);
241 	REG16(AX) = dst;
242 	CYCLES(CYCLES_ALU_IMM_ACC);
243 }
244 
i386_and_rm16_r16()245 void i386_device::i386_and_rm16_r16()      // Opcode 0x21
246 {
247 	uint16_t src, dst;
248 	uint8_t modrm = FETCH();
249 	if( modrm >= 0xc0 ) {
250 		src = LOAD_REG16(modrm);
251 		dst = LOAD_RM16(modrm);
252 		dst = AND16(dst, src);
253 		STORE_RM16(modrm, dst);
254 		CYCLES(CYCLES_ALU_REG_REG);
255 	} else {
256 		uint32_t ea = GetEA(modrm,1);
257 		src = LOAD_REG16(modrm);
258 		dst = READ16(ea);
259 		dst = AND16(dst, src);
260 		WRITE16(ea, dst);
261 		CYCLES(CYCLES_ALU_REG_MEM);
262 	}
263 }
264 
i386_and_r16_rm16()265 void i386_device::i386_and_r16_rm16()      // Opcode 0x23
266 {
267 	uint16_t src, dst;
268 	uint8_t modrm = FETCH();
269 	if( modrm >= 0xc0 ) {
270 		src = LOAD_RM16(modrm);
271 		dst = LOAD_REG16(modrm);
272 		dst = AND16(dst, src);
273 		STORE_REG16(modrm, dst);
274 		CYCLES(CYCLES_ALU_REG_REG);
275 	} else {
276 		uint32_t ea = GetEA(modrm,0);
277 		src = READ16(ea);
278 		dst = LOAD_REG16(modrm);
279 		dst = AND16(dst, src);
280 		STORE_REG16(modrm, dst);
281 		CYCLES(CYCLES_ALU_MEM_REG);
282 	}
283 }
284 
i386_and_ax_i16()285 void i386_device::i386_and_ax_i16()        // Opcode 0x25
286 {
287 	uint16_t src, dst;
288 	src = FETCH16();
289 	dst = REG16(AX);
290 	dst = AND16(dst, src);
291 	REG16(AX) = dst;
292 	CYCLES(CYCLES_ALU_IMM_ACC);
293 }
294 
i386_bsf_r16_rm16()295 void i386_device::i386_bsf_r16_rm16()      // Opcode 0x0f bc
296 {
297 	uint16_t src, dst, temp;
298 	uint8_t modrm = FETCH();
299 
300 	if( modrm >= 0xc0 ) {
301 		src = LOAD_RM16(modrm);
302 	} else {
303 		uint32_t ea = GetEA(modrm,0);
304 		src = READ16(ea);
305 	}
306 
307 	dst = 0;
308 
309 	if( src == 0 ) {
310 		m_ZF = 1;
311 	} else {
312 		m_ZF = 0;
313 		temp = 0;
314 		while( (src & (1 << temp)) == 0 ) {
315 			temp++;
316 			dst = temp;
317 			CYCLES(CYCLES_BSF);
318 		}
319 		STORE_REG16(modrm, dst);
320 	}
321 	CYCLES(CYCLES_BSF_BASE);
322 }
323 
i386_bsr_r16_rm16()324 void i386_device::i386_bsr_r16_rm16()      // Opcode 0x0f bd
325 {
326 	uint16_t src, dst, temp;
327 	uint8_t modrm = FETCH();
328 
329 	if( modrm >= 0xc0 ) {
330 		src = LOAD_RM16(modrm);
331 	} else {
332 		uint32_t ea = GetEA(modrm,0);
333 		src = READ16(ea);
334 	}
335 
336 	dst = 0;
337 
338 	if( src == 0 ) {
339 		m_ZF = 1;
340 	} else {
341 		m_ZF = 0;
342 		dst = temp = 15;
343 		while( (src & (1 << temp)) == 0 ) {
344 			temp--;
345 			dst = temp;
346 			CYCLES(CYCLES_BSR);
347 		}
348 		STORE_REG16(modrm, dst);
349 	}
350 	CYCLES(CYCLES_BSR_BASE);
351 }
352 
353 
i386_bt_rm16_r16()354 void i386_device::i386_bt_rm16_r16()       // Opcode 0x0f a3
355 {
356 	uint8_t modrm = FETCH();
357 	if( modrm >= 0xc0 ) {
358 		uint16_t dst = LOAD_RM16(modrm);
359 		uint16_t bit = LOAD_REG16(modrm);
360 
361 		if( dst & (1 << (bit & 0xf)) )
362 			m_CF = 1;
363 		else
364 			m_CF = 0;
365 
366 		CYCLES(CYCLES_BT_REG_REG);
367 	} else {
368 		uint8_t segment;
369 		uint32_t ea = GetNonTranslatedEA(modrm,&segment);
370 		uint16_t bit = LOAD_REG16(modrm);
371 		ea += 2*(bit/16);
372 		ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0);
373 		bit %= 16;
374 		uint16_t dst = READ16(ea);
375 
376 		if( dst & (1 << bit) )
377 			m_CF = 1;
378 		else
379 			m_CF = 0;
380 
381 		CYCLES(CYCLES_BT_REG_MEM);
382 	}
383 }
384 
i386_btc_rm16_r16()385 void i386_device::i386_btc_rm16_r16()      // Opcode 0x0f bb
386 {
387 	uint8_t modrm = FETCH();
388 	if( modrm >= 0xc0 ) {
389 		uint16_t dst = LOAD_RM16(modrm);
390 		uint16_t bit = LOAD_REG16(modrm);
391 
392 		if( dst & (1 << (bit & 0xf)) )
393 			m_CF = 1;
394 		else
395 			m_CF = 0;
396 		dst ^= (1 << (bit & 0xf));
397 
398 		STORE_RM16(modrm, dst);
399 		CYCLES(CYCLES_BTC_REG_REG);
400 	} else {
401 		uint8_t segment;
402 		uint32_t ea = GetNonTranslatedEA(modrm,&segment);
403 		uint16_t bit = LOAD_REG16(modrm);
404 		ea += 2*(bit/16);
405 		ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
406 		bit %= 16;
407 		uint16_t dst = READ16(ea);
408 
409 		if( dst & (1 << bit) )
410 			m_CF = 1;
411 		else
412 			m_CF = 0;
413 		dst ^= (1 << bit);
414 
415 		WRITE16(ea, dst);
416 		CYCLES(CYCLES_BTC_REG_MEM);
417 	}
418 }
419 
i386_btr_rm16_r16()420 void i386_device::i386_btr_rm16_r16()      // Opcode 0x0f b3
421 {
422 	uint8_t modrm = FETCH();
423 	if( modrm >= 0xc0 ) {
424 		uint16_t dst = LOAD_RM16(modrm);
425 		uint16_t bit = LOAD_REG16(modrm);
426 
427 		if( dst & (1 << (bit & 0xf)) )
428 			m_CF = 1;
429 		else
430 			m_CF = 0;
431 		dst &= ~(1 << (bit & 0xf));
432 
433 		STORE_RM16(modrm, dst);
434 		CYCLES(CYCLES_BTR_REG_REG);
435 	} else {
436 		uint8_t segment;
437 		uint32_t ea = GetNonTranslatedEA(modrm,&segment);
438 		uint16_t bit = LOAD_REG16(modrm);
439 		ea += 2*(bit/16);
440 		ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
441 		bit %= 16;
442 		uint16_t dst = READ16(ea);
443 
444 		if( dst & (1 << bit) )
445 			m_CF = 1;
446 		else
447 			m_CF = 0;
448 		dst &= ~(1 << bit);
449 
450 		WRITE16(ea, dst);
451 		CYCLES(CYCLES_BTR_REG_MEM);
452 	}
453 }
454 
i386_bts_rm16_r16()455 void i386_device::i386_bts_rm16_r16()      // Opcode 0x0f ab
456 {
457 	uint8_t modrm = FETCH();
458 	if( modrm >= 0xc0 ) {
459 		uint16_t dst = LOAD_RM16(modrm);
460 		uint16_t bit = LOAD_REG16(modrm);
461 
462 		if( dst & (1 << (bit & 0xf)) )
463 			m_CF = 1;
464 		else
465 			m_CF = 0;
466 		dst |= (1 << (bit & 0xf));
467 
468 		STORE_RM16(modrm, dst);
469 		CYCLES(CYCLES_BTS_REG_REG);
470 	} else {
471 		uint8_t segment;
472 		uint32_t ea = GetNonTranslatedEA(modrm,&segment);
473 		uint16_t bit = LOAD_REG16(modrm);
474 		ea += 2*(bit/16);
475 		ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1);
476 		bit %= 16;
477 		uint16_t dst = READ16(ea);
478 
479 		if( dst & (1 << bit) )
480 			m_CF = 1;
481 		else
482 			m_CF = 0;
483 		dst |= (1 << bit);
484 
485 		WRITE16(ea, dst);
486 		CYCLES(CYCLES_BTS_REG_MEM);
487 	}
488 }
489 
i386_call_abs16()490 void i386_device::i386_call_abs16()        // Opcode 0x9a
491 {
492 	uint16_t offset = FETCH16();
493 	uint16_t ptr = FETCH16();
494 
495 	if( PROTECTED_MODE && !V8086_MODE)
496 	{
497 		i386_protected_mode_call(ptr,offset,0,0);
498 	}
499 	else
500 	{
501 		PUSH16(m_sreg[CS].selector );
502 		PUSH16(m_eip );
503 		m_sreg[CS].selector = ptr;
504 		m_performed_intersegment_jump = 1;
505 		m_eip = offset;
506 		i386_load_segment_descriptor(CS);
507 	}
508 	CYCLES(CYCLES_CALL_INTERSEG);      /* TODO: Timing = 17 + m */
509 	CHANGE_PC(m_eip);
510 }
511 
i386_call_rel16()512 void i386_device::i386_call_rel16()        // Opcode 0xe8
513 {
514 	int16_t disp = FETCH16();
515 
516 	PUSH16(m_eip );
517 	if (m_sreg[CS].d)
518 	{
519 		m_eip += disp;
520 	}
521 	else
522 	{
523 		m_eip = (m_eip + disp) & 0xffff;
524 	}
525 	CHANGE_PC(m_eip);
526 	CYCLES(CYCLES_CALL);       /* TODO: Timing = 7 + m */
527 }
528 
i386_cbw()529 void i386_device::i386_cbw()               // Opcode 0x98
530 {
531 	REG16(AX) = (int16_t)((int8_t)REG8(AL));
532 	CYCLES(CYCLES_CBW);
533 }
534 
i386_cmp_rm16_r16()535 void i386_device::i386_cmp_rm16_r16()      // Opcode 0x39
536 {
537 	uint16_t src, dst;
538 	uint8_t modrm = FETCH();
539 	if( modrm >= 0xc0 ) {
540 		src = LOAD_REG16(modrm);
541 		dst = LOAD_RM16(modrm);
542 		SUB16(dst, src);
543 		CYCLES(CYCLES_CMP_REG_REG);
544 	} else {
545 		uint32_t ea = GetEA(modrm,0);
546 		src = LOAD_REG16(modrm);
547 		dst = READ16(ea);
548 		SUB16(dst, src);
549 		CYCLES(CYCLES_CMP_REG_MEM);
550 	}
551 }
552 
i386_cmp_r16_rm16()553 void i386_device::i386_cmp_r16_rm16()      // Opcode 0x3b
554 {
555 	uint16_t src, dst;
556 	uint8_t modrm = FETCH();
557 	if( modrm >= 0xc0 ) {
558 		src = LOAD_RM16(modrm);
559 		dst = LOAD_REG16(modrm);
560 		SUB16(dst, src);
561 		CYCLES(CYCLES_CMP_REG_REG);
562 	} else {
563 		uint32_t ea = GetEA(modrm,0);
564 		src = READ16(ea);
565 		dst = LOAD_REG16(modrm);
566 		SUB16(dst, src);
567 		CYCLES(CYCLES_CMP_MEM_REG);
568 	}
569 }
570 
i386_cmp_ax_i16()571 void i386_device::i386_cmp_ax_i16()        // Opcode 0x3d
572 {
573 	uint16_t src, dst;
574 	src = FETCH16();
575 	dst = REG16(AX);
576 	SUB16(dst, src);
577 	CYCLES(CYCLES_CMP_IMM_ACC);
578 }
579 
i386_cmpsw()580 void i386_device::i386_cmpsw()             // Opcode 0xa7
581 {
582 	uint32_t eas, ead;
583 	uint16_t src, dst;
584 	if( m_segment_prefix ) {
585 		eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
586 	} else {
587 		eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
588 	}
589 	ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
590 	src = READ16(eas);
591 	dst = READ16(ead);
592 	SUB16(src,dst);
593 	BUMP_SI(2);
594 	BUMP_DI(2);
595 	CYCLES(CYCLES_CMPS);
596 }
597 
i386_cwd()598 void i386_device::i386_cwd()               // Opcode 0x99
599 {
600 	if( REG16(AX) & 0x8000 ) {
601 		REG16(DX) = 0xffff;
602 	} else {
603 		REG16(DX) = 0x0000;
604 	}
605 	CYCLES(CYCLES_CWD);
606 }
607 
i386_dec_ax()608 void i386_device::i386_dec_ax()            // Opcode 0x48
609 {
610 	REG16(AX) = DEC16(REG16(AX) );
611 	CYCLES(CYCLES_DEC_REG);
612 }
613 
i386_dec_cx()614 void i386_device::i386_dec_cx()            // Opcode 0x49
615 {
616 	REG16(CX) = DEC16(REG16(CX) );
617 	CYCLES(CYCLES_DEC_REG);
618 }
619 
i386_dec_dx()620 void i386_device::i386_dec_dx()            // Opcode 0x4a
621 {
622 	REG16(DX) = DEC16(REG16(DX) );
623 	CYCLES(CYCLES_DEC_REG);
624 }
625 
i386_dec_bx()626 void i386_device::i386_dec_bx()            // Opcode 0x4b
627 {
628 	REG16(BX) = DEC16(REG16(BX) );
629 	CYCLES(CYCLES_DEC_REG);
630 }
631 
i386_dec_sp()632 void i386_device::i386_dec_sp()            // Opcode 0x4c
633 {
634 	REG16(SP) = DEC16(REG16(SP) );
635 	CYCLES(CYCLES_DEC_REG);
636 }
637 
i386_dec_bp()638 void i386_device::i386_dec_bp()            // Opcode 0x4d
639 {
640 	REG16(BP) = DEC16(REG16(BP) );
641 	CYCLES(CYCLES_DEC_REG);
642 }
643 
i386_dec_si()644 void i386_device::i386_dec_si()            // Opcode 0x4e
645 {
646 	REG16(SI) = DEC16(REG16(SI) );
647 	CYCLES(CYCLES_DEC_REG);
648 }
649 
i386_dec_di()650 void i386_device::i386_dec_di()            // Opcode 0x4f
651 {
652 	REG16(DI) = DEC16(REG16(DI) );
653 	CYCLES(CYCLES_DEC_REG);
654 }
655 
i386_imul_r16_rm16()656 void i386_device::i386_imul_r16_rm16()     // Opcode 0x0f af
657 {
658 	uint8_t modrm = FETCH();
659 	int32_t result;
660 	int32_t src, dst;
661 	if( modrm >= 0xc0 ) {
662 		src = (int32_t)(int16_t)LOAD_RM16(modrm);
663 		CYCLES(CYCLES_IMUL16_REG_REG);     /* TODO: Correct multiply timing */
664 	} else {
665 		uint32_t ea = GetEA(modrm,0);
666 		src = (int32_t)(int16_t)READ16(ea);
667 		CYCLES(CYCLES_IMUL16_REG_MEM);     /* TODO: Correct multiply timing */
668 	}
669 
670 	dst = (int32_t)(int16_t)LOAD_REG16(modrm);
671 	result = src * dst;
672 
673 	STORE_REG16(modrm, (uint16_t)result);
674 
675 	m_CF = m_OF = !(result == (int32_t)(int16_t)result);
676 }
677 
i386_imul_r16_rm16_i16()678 void i386_device::i386_imul_r16_rm16_i16() // Opcode 0x69
679 {
680 	uint8_t modrm = FETCH();
681 	int32_t result;
682 	int32_t src, dst;
683 	if( modrm >= 0xc0 ) {
684 		dst = (int32_t)(int16_t)LOAD_RM16(modrm);
685 		CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
686 	} else {
687 		uint32_t ea = GetEA(modrm,0);
688 		dst = (int32_t)(int16_t)READ16(ea);
689 		CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
690 	}
691 
692 	src = (int32_t)(int16_t)FETCH16();
693 	result = src * dst;
694 
695 	STORE_REG16(modrm, (uint16_t)result);
696 
697 	m_CF = m_OF = !(result == (int32_t)(int16_t)result);
698 }
699 
i386_imul_r16_rm16_i8()700 void i386_device::i386_imul_r16_rm16_i8()  // Opcode 0x6b
701 {
702 	uint8_t modrm = FETCH();
703 	int32_t result;
704 	int32_t src, dst;
705 	if( modrm >= 0xc0 ) {
706 		dst = (int32_t)(int16_t)LOAD_RM16(modrm);
707 		CYCLES(CYCLES_IMUL16_REG_IMM_REG);     /* TODO: Correct multiply timing */
708 	} else {
709 		uint32_t ea = GetEA(modrm,0);
710 		dst = (int32_t)(int16_t)READ16(ea);
711 		CYCLES(CYCLES_IMUL16_MEM_IMM_REG);     /* TODO: Correct multiply timing */
712 	}
713 
714 	src = (int32_t)(int8_t)FETCH();
715 	result = src * dst;
716 
717 	STORE_REG16(modrm, (uint16_t)result);
718 
719 	m_CF = m_OF = !(result == (int32_t)(int16_t)result);
720 }
721 
i386_in_ax_i8()722 void i386_device::i386_in_ax_i8()          // Opcode 0xe5
723 {
724 	uint16_t port = FETCH();
725 	uint16_t data = READPORT16(port);
726 	REG16(AX) = data;
727 	CYCLES(CYCLES_IN_VAR);
728 }
729 
i386_in_ax_dx()730 void i386_device::i386_in_ax_dx()          // Opcode 0xed
731 {
732 	uint16_t port = REG16(DX);
733 	uint16_t data = READPORT16(port);
734 	REG16(AX) = data;
735 	CYCLES(CYCLES_IN);
736 }
737 
i386_inc_ax()738 void i386_device::i386_inc_ax()            // Opcode 0x40
739 {
740 	REG16(AX) = INC16(REG16(AX) );
741 	CYCLES(CYCLES_INC_REG);
742 }
743 
i386_inc_cx()744 void i386_device::i386_inc_cx()            // Opcode 0x41
745 {
746 	REG16(CX) = INC16(REG16(CX) );
747 	CYCLES(CYCLES_INC_REG);
748 }
749 
i386_inc_dx()750 void i386_device::i386_inc_dx()            // Opcode 0x42
751 {
752 	REG16(DX) = INC16(REG16(DX) );
753 	CYCLES(CYCLES_INC_REG);
754 }
755 
i386_inc_bx()756 void i386_device::i386_inc_bx()            // Opcode 0x43
757 {
758 	REG16(BX) = INC16(REG16(BX) );
759 	CYCLES(CYCLES_INC_REG);
760 }
761 
i386_inc_sp()762 void i386_device::i386_inc_sp()            // Opcode 0x44
763 {
764 	REG16(SP) = INC16(REG16(SP) );
765 	CYCLES(CYCLES_INC_REG);
766 }
767 
i386_inc_bp()768 void i386_device::i386_inc_bp()            // Opcode 0x45
769 {
770 	REG16(BP) = INC16(REG16(BP) );
771 	CYCLES(CYCLES_INC_REG);
772 }
773 
i386_inc_si()774 void i386_device::i386_inc_si()            // Opcode 0x46
775 {
776 	REG16(SI) = INC16(REG16(SI) );
777 	CYCLES(CYCLES_INC_REG);
778 }
779 
i386_inc_di()780 void i386_device::i386_inc_di()            // Opcode 0x47
781 {
782 	REG16(DI) = INC16(REG16(DI) );
783 	CYCLES(CYCLES_INC_REG);
784 }
785 
i386_iret16()786 void i386_device::i386_iret16()            // Opcode 0xcf
787 {
788 	if( PROTECTED_MODE )
789 	{
790 		i386_protected_mode_iret(0);
791 	}
792 	else
793 	{
794 		/* TODO: #SS(0) exception */
795 		/* TODO: #GP(0) exception */
796 		m_eip = POP16();
797 		m_sreg[CS].selector = POP16();
798 		set_flags(POP16() );
799 		i386_load_segment_descriptor(CS);
800 		CHANGE_PC(m_eip);
801 	}
802 	m_auto_clear_RF = false;
803 	CYCLES(CYCLES_IRET);
804 }
805 
i386_ja_rel16()806 void i386_device::i386_ja_rel16()          // Opcode 0x0f 87
807 {
808 	int16_t disp = FETCH16();
809 	if( m_CF == 0 && m_ZF == 0 ) {
810 		if (m_sreg[CS].d)
811 		{
812 			m_eip += disp;
813 		}
814 		else
815 		{
816 			m_eip = (m_eip + disp) & 0xffff;
817 		}
818 		CHANGE_PC(m_eip);
819 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
820 	} else {
821 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
822 	}
823 }
824 
i386_jbe_rel16()825 void i386_device::i386_jbe_rel16()         // Opcode 0x0f 86
826 {
827 	int16_t disp = FETCH16();
828 	if( m_CF != 0 || m_ZF != 0 ) {
829 		if (m_sreg[CS].d)
830 		{
831 			m_eip += disp;
832 		}
833 		else
834 		{
835 			m_eip = (m_eip + disp) & 0xffff;
836 		}
837 		CHANGE_PC(m_eip);
838 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
839 	} else {
840 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
841 	}
842 }
843 
i386_jc_rel16()844 void i386_device::i386_jc_rel16()          // Opcode 0x0f 82
845 {
846 	int16_t disp = FETCH16();
847 	if( m_CF != 0 ) {
848 		if (m_sreg[CS].d)
849 		{
850 			m_eip += disp;
851 		}
852 		else
853 		{
854 			m_eip = (m_eip + disp) & 0xffff;
855 		}
856 		CHANGE_PC(m_eip);
857 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
858 	} else {
859 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
860 	}
861 }
862 
i386_jg_rel16()863 void i386_device::i386_jg_rel16()          // Opcode 0x0f 8f
864 {
865 	int16_t disp = FETCH16();
866 	if( m_ZF == 0 && (m_SF == m_OF) ) {
867 		if (m_sreg[CS].d)
868 		{
869 			m_eip += disp;
870 		}
871 		else
872 		{
873 			m_eip = (m_eip + disp) & 0xffff;
874 		}
875 		CHANGE_PC(m_eip);
876 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
877 	} else {
878 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
879 	}
880 }
881 
i386_jge_rel16()882 void i386_device::i386_jge_rel16()         // Opcode 0x0f 8d
883 {
884 	int16_t disp = FETCH16();
885 	if(m_SF == m_OF) {
886 		if (m_sreg[CS].d)
887 		{
888 			m_eip += disp;
889 		}
890 		else
891 		{
892 			m_eip = (m_eip + disp) & 0xffff;
893 		}
894 		CHANGE_PC(m_eip);
895 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
896 	} else {
897 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
898 	}
899 }
900 
i386_jl_rel16()901 void i386_device::i386_jl_rel16()          // Opcode 0x0f 8c
902 {
903 	int16_t disp = FETCH16();
904 	if( (m_SF != m_OF) ) {
905 		if (m_sreg[CS].d)
906 		{
907 			m_eip += disp;
908 		}
909 		else
910 		{
911 			m_eip = (m_eip + disp) & 0xffff;
912 		}
913 		CHANGE_PC(m_eip);
914 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
915 	} else {
916 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
917 	}
918 }
919 
i386_jle_rel16()920 void i386_device::i386_jle_rel16()         // Opcode 0x0f 8e
921 {
922 	int16_t disp = FETCH16();
923 	if( m_ZF != 0 || (m_SF != m_OF) ) {
924 		if (m_sreg[CS].d)
925 		{
926 			m_eip += disp;
927 		}
928 		else
929 		{
930 			m_eip = (m_eip + disp) & 0xffff;
931 		}
932 		CHANGE_PC(m_eip);
933 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
934 	} else {
935 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
936 	}
937 }
938 
i386_jnc_rel16()939 void i386_device::i386_jnc_rel16()         // Opcode 0x0f 83
940 {
941 	int16_t disp = FETCH16();
942 	if( m_CF == 0 ) {
943 		if (m_sreg[CS].d)
944 		{
945 			m_eip += disp;
946 		}
947 		else
948 		{
949 			m_eip = (m_eip + disp) & 0xffff;
950 		}
951 		CHANGE_PC(m_eip);
952 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
953 	} else {
954 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
955 	}
956 }
957 
i386_jno_rel16()958 void i386_device::i386_jno_rel16()         // Opcode 0x0f 81
959 {
960 	int16_t disp = FETCH16();
961 	if( m_OF == 0 ) {
962 		if (m_sreg[CS].d)
963 		{
964 			m_eip += disp;
965 		}
966 		else
967 		{
968 			m_eip = (m_eip + disp) & 0xffff;
969 		}
970 		CHANGE_PC(m_eip);
971 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
972 	} else {
973 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
974 	}
975 }
976 
i386_jnp_rel16()977 void i386_device::i386_jnp_rel16()         // Opcode 0x0f 8b
978 {
979 	int16_t disp = FETCH16();
980 	if( m_PF == 0 ) {
981 		if (m_sreg[CS].d)
982 		{
983 			m_eip += disp;
984 		}
985 		else
986 		{
987 			m_eip = (m_eip + disp) & 0xffff;
988 		}
989 		CHANGE_PC(m_eip);
990 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
991 	} else {
992 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
993 	}
994 }
995 
i386_jns_rel16()996 void i386_device::i386_jns_rel16()         // Opcode 0x0f 89
997 {
998 	int16_t disp = FETCH16();
999 	if( m_SF == 0 ) {
1000 		if (m_sreg[CS].d)
1001 		{
1002 			m_eip += disp;
1003 		}
1004 		else
1005 		{
1006 			m_eip = (m_eip + disp) & 0xffff;
1007 		}
1008 		CHANGE_PC(m_eip);
1009 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1010 	} else {
1011 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1012 	}
1013 }
1014 
i386_jnz_rel16()1015 void i386_device::i386_jnz_rel16()         // Opcode 0x0f 85
1016 {
1017 	int16_t disp = FETCH16();
1018 	if( m_ZF == 0 ) {
1019 		if (m_sreg[CS].d)
1020 		{
1021 			m_eip += disp;
1022 		}
1023 		else
1024 		{
1025 			m_eip = (m_eip + disp) & 0xffff;
1026 		}
1027 		CHANGE_PC(m_eip);
1028 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1029 	} else {
1030 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1031 	}
1032 }
1033 
i386_jo_rel16()1034 void i386_device::i386_jo_rel16()          // Opcode 0x0f 80
1035 {
1036 	int16_t disp = FETCH16();
1037 	if( m_OF != 0 ) {
1038 		if (m_sreg[CS].d)
1039 		{
1040 			m_eip += disp;
1041 		}
1042 		else
1043 		{
1044 			m_eip = (m_eip + disp) & 0xffff;
1045 		}
1046 		CHANGE_PC(m_eip);
1047 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1048 	} else {
1049 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1050 	}
1051 }
1052 
i386_jp_rel16()1053 void i386_device::i386_jp_rel16()          // Opcode 0x0f 8a
1054 {
1055 	int16_t disp = FETCH16();
1056 	if( m_PF != 0 ) {
1057 		if (m_sreg[CS].d)
1058 		{
1059 			m_eip += disp;
1060 		}
1061 		else
1062 		{
1063 			m_eip = (m_eip + disp) & 0xffff;
1064 		}
1065 		CHANGE_PC(m_eip);
1066 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1067 	} else {
1068 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1069 	}
1070 }
1071 
i386_js_rel16()1072 void i386_device::i386_js_rel16()          // Opcode 0x0f 88
1073 {
1074 	int16_t disp = FETCH16();
1075 	if( m_SF != 0 ) {
1076 		if (m_sreg[CS].d)
1077 		{
1078 			m_eip += disp;
1079 		}
1080 		else
1081 		{
1082 			m_eip = (m_eip + disp) & 0xffff;
1083 		}
1084 		CHANGE_PC(m_eip);
1085 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1086 	} else {
1087 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1088 	}
1089 }
1090 
i386_jz_rel16()1091 void i386_device::i386_jz_rel16()          // Opcode 0x0f 84
1092 {
1093 	int16_t disp = FETCH16();
1094 	if( m_ZF != 0 ) {
1095 		if (m_sreg[CS].d)
1096 		{
1097 			m_eip += disp;
1098 		}
1099 		else
1100 		{
1101 			m_eip = (m_eip + disp) & 0xffff;
1102 		}
1103 		CHANGE_PC(m_eip);
1104 		CYCLES(CYCLES_JCC_FULL_DISP);      /* TODO: Timing = 7 + m */
1105 	} else {
1106 		CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH);
1107 	}
1108 }
1109 
i386_jcxz16()1110 void i386_device::i386_jcxz16()            // Opcode 0xe3
1111 {
1112 	int8_t disp = FETCH();
1113 	int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0);
1114 	if( val ) {
1115 		if (m_sreg[CS].d)
1116 		{
1117 			m_eip += disp;
1118 		}
1119 		else
1120 		{
1121 			m_eip = (m_eip + disp) & 0xffff;
1122 		}
1123 		CHANGE_PC(m_eip);
1124 		CYCLES(CYCLES_JCXZ);       /* TODO: Timing = 9 + m */
1125 	} else {
1126 		CYCLES(CYCLES_JCXZ_NOBRANCH);
1127 	}
1128 }
1129 
i386_jmp_rel16()1130 void i386_device::i386_jmp_rel16()         // Opcode 0xe9
1131 {
1132 	int16_t disp = FETCH16();
1133 
1134 	if (m_sreg[CS].d)
1135 	{
1136 		m_eip += disp;
1137 	}
1138 	else
1139 	{
1140 		m_eip = (m_eip + disp) & 0xffff;
1141 	}
1142 	CHANGE_PC(m_eip);
1143 	CYCLES(CYCLES_JMP);        /* TODO: Timing = 7 + m */
1144 }
1145 
i386_jmp_abs16()1146 void i386_device::i386_jmp_abs16()         // Opcode 0xea
1147 {
1148 	uint16_t address = FETCH16();
1149 	uint16_t segment = FETCH16();
1150 
1151 	if( PROTECTED_MODE && !V8086_MODE)
1152 	{
1153 		i386_protected_mode_jump(segment,address,0,0);
1154 	}
1155 	else
1156 	{
1157 		m_eip = address;
1158 		m_sreg[CS].selector = segment;
1159 		m_performed_intersegment_jump = 1;
1160 		i386_load_segment_descriptor(CS);
1161 		CHANGE_PC(m_eip);
1162 	}
1163 	CYCLES(CYCLES_JMP_INTERSEG);
1164 }
1165 
i386_lea16()1166 void i386_device::i386_lea16()             // Opcode 0x8d
1167 {
1168 	uint8_t modrm = FETCH();
1169 	uint32_t ea = GetNonTranslatedEA(modrm,nullptr);
1170 	STORE_REG16(modrm, ea);
1171 	CYCLES(CYCLES_LEA);
1172 }
1173 
i386_enter16()1174 void i386_device::i386_enter16()           // Opcode 0xc8
1175 {
1176 	uint16_t framesize = FETCH16();
1177 	uint8_t level = FETCH() % 32;
1178 	uint8_t x;
1179 	uint16_t frameptr;
1180 	PUSH16(REG16(BP));
1181 
1182 	if(!STACK_32BIT)
1183 		frameptr = REG16(SP);
1184 	else
1185 		frameptr = REG32(ESP);
1186 
1187 	if(level > 0)
1188 	{
1189 		for(x=1;x<=level-1;x++)
1190 		{
1191 			uint32_t addr;
1192 			if(!STACK_32BIT)
1193 			{
1194 				REG16(BP) -= 2;
1195 				addr = REG16(BP);
1196 			}
1197 			else
1198 			{
1199 				REG32(EBP) -= 2;
1200 				addr = REG32(EBP);
1201 			}
1202 			PUSH16(READ16(i386_translate(SS, addr, 0)));
1203 		}
1204 		PUSH16(frameptr);
1205 	}
1206 	REG16(BP) = frameptr;
1207 	if(!STACK_32BIT)
1208 		REG16(SP) -= framesize;
1209 	else
1210 		REG32(ESP) -= framesize;
1211 	CYCLES(CYCLES_ENTER);
1212 }
1213 
i386_leave16()1214 void i386_device::i386_leave16()           // Opcode 0xc9
1215 {
1216 	if(!STACK_32BIT)
1217 		REG16(SP) = REG16(BP);
1218 	else
1219 		REG32(ESP) = REG32(EBP);
1220 	REG16(BP) = POP16();
1221 	CYCLES(CYCLES_LEAVE);
1222 }
1223 
i386_lodsw()1224 void i386_device::i386_lodsw()             // Opcode 0xad
1225 {
1226 	uint32_t eas;
1227 	if( m_segment_prefix ) {
1228 		eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1229 	} else {
1230 		eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1231 	}
1232 	REG16(AX) = READ16(eas);
1233 	BUMP_SI(2);
1234 	CYCLES(CYCLES_LODS);
1235 }
1236 
i386_loop16()1237 void i386_device::i386_loop16()            // Opcode 0xe2
1238 {
1239 	int8_t disp = FETCH();
1240 	int32_t val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1241 	if( val != 0 ) {
1242 		if (m_sreg[CS].d)
1243 		{
1244 			m_eip += disp;
1245 		}
1246 		else
1247 		{
1248 			m_eip = (m_eip + disp) & 0xffff;
1249 		}
1250 		CHANGE_PC(m_eip);
1251 	}
1252 	CYCLES(CYCLES_LOOP);       /* TODO: Timing = 11 + m */
1253 }
1254 
i386_loopne16()1255 void i386_device::i386_loopne16()          // Opcode 0xe0
1256 {
1257 	int8_t disp = FETCH();
1258 	int32_t val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1259 	if( val != 0 && m_ZF == 0 ) {
1260 		if (m_sreg[CS].d)
1261 		{
1262 			m_eip += disp;
1263 		}
1264 		else
1265 		{
1266 			m_eip = (m_eip + disp) & 0xffff;
1267 		}
1268 		CHANGE_PC(m_eip);
1269 	}
1270 	CYCLES(CYCLES_LOOPNZ);     /* TODO: Timing = 11 + m */
1271 }
1272 
i386_loopz16()1273 void i386_device::i386_loopz16()           // Opcode 0xe1
1274 {
1275 	int8_t disp = FETCH();
1276 	int32_t val = (m_address_size)?(--REG32(ECX)):(--REG16(CX));
1277 	if( val != 0 && m_ZF != 0 ) {
1278 		if (m_sreg[CS].d)
1279 		{
1280 			m_eip += disp;
1281 		}
1282 		else
1283 		{
1284 			m_eip = (m_eip + disp) & 0xffff;
1285 		}
1286 		CHANGE_PC(m_eip);
1287 	}
1288 	CYCLES(CYCLES_LOOPZ);      /* TODO: Timing = 11 + m */
1289 }
1290 
i386_mov_rm16_r16()1291 void i386_device::i386_mov_rm16_r16()      // Opcode 0x89
1292 {
1293 	uint16_t src;
1294 	uint8_t modrm = FETCH();
1295 	if( modrm >= 0xc0 ) {
1296 		src = LOAD_REG16(modrm);
1297 		STORE_RM16(modrm, src);
1298 		CYCLES(CYCLES_MOV_REG_REG);
1299 	} else {
1300 		uint32_t ea = GetEA(modrm,1);
1301 		src = LOAD_REG16(modrm);
1302 		WRITE16(ea, src);
1303 		CYCLES(CYCLES_MOV_REG_MEM);
1304 	}
1305 }
1306 
i386_mov_r16_rm16()1307 void i386_device::i386_mov_r16_rm16()      // Opcode 0x8b
1308 {
1309 	uint16_t src;
1310 	uint8_t modrm = FETCH();
1311 	if( modrm >= 0xc0 ) {
1312 		src = LOAD_RM16(modrm);
1313 		STORE_REG16(modrm, src);
1314 		CYCLES(CYCLES_MOV_REG_REG);
1315 	} else {
1316 		uint32_t ea = GetEA(modrm,0);
1317 		src = READ16(ea);
1318 		STORE_REG16(modrm, src);
1319 		CYCLES(CYCLES_MOV_MEM_REG);
1320 	}
1321 }
1322 
i386_mov_rm16_i16()1323 void i386_device::i386_mov_rm16_i16()      // Opcode 0xc7
1324 {
1325 	uint8_t modrm = FETCH();
1326 	if( modrm >= 0xc0 ) {
1327 		uint16_t value = FETCH16();
1328 		STORE_RM16(modrm, value);
1329 		CYCLES(CYCLES_MOV_IMM_REG);
1330 	} else {
1331 		uint32_t ea = GetEA(modrm,1);
1332 		uint16_t value = FETCH16();
1333 		WRITE16(ea, value);
1334 		CYCLES(CYCLES_MOV_IMM_MEM);
1335 	}
1336 }
1337 
i386_mov_ax_m16()1338 void i386_device::i386_mov_ax_m16()        // Opcode 0xa1
1339 {
1340 	uint32_t offset, ea;
1341 	if( m_address_size ) {
1342 		offset = FETCH32();
1343 	} else {
1344 		offset = FETCH16();
1345 	}
1346 	/* TODO: Not sure if this is correct... */
1347 	if( m_segment_prefix ) {
1348 		ea = i386_translate(m_segment_override, offset, 0 );
1349 	} else {
1350 		ea = i386_translate(DS, offset, 0 );
1351 	}
1352 	REG16(AX) = READ16(ea);
1353 	CYCLES(CYCLES_MOV_MEM_ACC);
1354 }
1355 
i386_mov_m16_ax()1356 void i386_device::i386_mov_m16_ax()        // Opcode 0xa3
1357 {
1358 	uint32_t offset, ea;
1359 	if( m_address_size ) {
1360 		offset = FETCH32();
1361 	} else {
1362 		offset = FETCH16();
1363 	}
1364 	/* TODO: Not sure if this is correct... */
1365 	if( m_segment_prefix ) {
1366 		ea = i386_translate(m_segment_override, offset, 1 );
1367 	} else {
1368 		ea = i386_translate(DS, offset, 1 );
1369 	}
1370 	WRITE16(ea, REG16(AX) );
1371 	CYCLES(CYCLES_MOV_ACC_MEM);
1372 }
1373 
i386_mov_ax_i16()1374 void i386_device::i386_mov_ax_i16()        // Opcode 0xb8
1375 {
1376 	REG16(AX) = FETCH16();
1377 	CYCLES(CYCLES_MOV_IMM_REG);
1378 }
1379 
i386_mov_cx_i16()1380 void i386_device::i386_mov_cx_i16()        // Opcode 0xb9
1381 {
1382 	REG16(CX) = FETCH16();
1383 	CYCLES(CYCLES_MOV_IMM_REG);
1384 }
1385 
i386_mov_dx_i16()1386 void i386_device::i386_mov_dx_i16()        // Opcode 0xba
1387 {
1388 	REG16(DX) = FETCH16();
1389 	CYCLES(CYCLES_MOV_IMM_REG);
1390 }
1391 
i386_mov_bx_i16()1392 void i386_device::i386_mov_bx_i16()        // Opcode 0xbb
1393 {
1394 	REG16(BX) = FETCH16();
1395 	CYCLES(CYCLES_MOV_IMM_REG);
1396 }
1397 
i386_mov_sp_i16()1398 void i386_device::i386_mov_sp_i16()        // Opcode 0xbc
1399 {
1400 	REG16(SP) = FETCH16();
1401 	CYCLES(CYCLES_MOV_IMM_REG);
1402 }
1403 
i386_mov_bp_i16()1404 void i386_device::i386_mov_bp_i16()        // Opcode 0xbd
1405 {
1406 	REG16(BP) = FETCH16();
1407 	CYCLES(CYCLES_MOV_IMM_REG);
1408 }
1409 
i386_mov_si_i16()1410 void i386_device::i386_mov_si_i16()        // Opcode 0xbe
1411 {
1412 	REG16(SI) = FETCH16();
1413 	CYCLES(CYCLES_MOV_IMM_REG);
1414 }
1415 
i386_mov_di_i16()1416 void i386_device::i386_mov_di_i16()        // Opcode 0xbf
1417 {
1418 	REG16(DI) = FETCH16();
1419 	CYCLES(CYCLES_MOV_IMM_REG);
1420 }
1421 
i386_movsw()1422 void i386_device::i386_movsw()             // Opcode 0xa5
1423 {
1424 	uint32_t eas, ead;
1425 	uint16_t v;
1426 	if( m_segment_prefix ) {
1427 		eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1428 	} else {
1429 		eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 );
1430 	}
1431 	ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
1432 	v = READ16(eas);
1433 	WRITE16(ead, v);
1434 	BUMP_SI(2);
1435 	BUMP_DI(2);
1436 	CYCLES(CYCLES_MOVS);
1437 }
1438 
i386_movsx_r16_rm8()1439 void i386_device::i386_movsx_r16_rm8()     // Opcode 0x0f be
1440 {
1441 	uint8_t modrm = FETCH();
1442 	if( modrm >= 0xc0 ) {
1443 		int16_t src = (int8_t)LOAD_RM8(modrm);
1444 		STORE_REG16(modrm, src);
1445 		CYCLES(CYCLES_MOVSX_REG_REG);
1446 	} else {
1447 		uint32_t ea = GetEA(modrm,0);
1448 		int16_t src = (int8_t)READ8(ea);
1449 		STORE_REG16(modrm, src);
1450 		CYCLES(CYCLES_MOVSX_MEM_REG);
1451 	}
1452 }
1453 
i386_movzx_r16_rm8()1454 void i386_device::i386_movzx_r16_rm8()     // Opcode 0x0f b6
1455 {
1456 	uint8_t modrm = FETCH();
1457 	if( modrm >= 0xc0 ) {
1458 		uint16_t src = (uint8_t)LOAD_RM8(modrm);
1459 		STORE_REG16(modrm, src);
1460 		CYCLES(CYCLES_MOVZX_REG_REG);
1461 	} else {
1462 		uint32_t ea = GetEA(modrm,0);
1463 		uint16_t src = (uint8_t)READ8(ea);
1464 		STORE_REG16(modrm, src);
1465 		CYCLES(CYCLES_MOVZX_MEM_REG);
1466 	}
1467 }
1468 
i386_or_rm16_r16()1469 void i386_device::i386_or_rm16_r16()       // Opcode 0x09
1470 {
1471 	uint16_t src, dst;
1472 	uint8_t modrm = FETCH();
1473 	if( modrm >= 0xc0 ) {
1474 		src = LOAD_REG16(modrm);
1475 		dst = LOAD_RM16(modrm);
1476 		dst = OR16(dst, src);
1477 		STORE_RM16(modrm, dst);
1478 		CYCLES(CYCLES_ALU_REG_REG);
1479 	} else {
1480 		uint32_t ea = GetEA(modrm,1);
1481 		src = LOAD_REG16(modrm);
1482 		dst = READ16(ea);
1483 		dst = OR16(dst, src);
1484 		WRITE16(ea, dst);
1485 		CYCLES(CYCLES_ALU_REG_MEM);
1486 	}
1487 }
1488 
i386_or_r16_rm16()1489 void i386_device::i386_or_r16_rm16()       // Opcode 0x0b
1490 {
1491 	uint16_t src, dst;
1492 	uint8_t modrm = FETCH();
1493 	if( modrm >= 0xc0 ) {
1494 		src = LOAD_RM16(modrm);
1495 		dst = LOAD_REG16(modrm);
1496 		dst = OR16(dst, src);
1497 		STORE_REG16(modrm, dst);
1498 		CYCLES(CYCLES_ALU_REG_REG);
1499 	} else {
1500 		uint32_t ea = GetEA(modrm,0);
1501 		src = READ16(ea);
1502 		dst = LOAD_REG16(modrm);
1503 		dst = OR16(dst, src);
1504 		STORE_REG16(modrm, dst);
1505 		CYCLES(CYCLES_ALU_MEM_REG);
1506 	}
1507 }
1508 
i386_or_ax_i16()1509 void i386_device::i386_or_ax_i16()         // Opcode 0x0d
1510 {
1511 	uint16_t src, dst;
1512 	src = FETCH16();
1513 	dst = REG16(AX);
1514 	dst = OR16(dst, src);
1515 	REG16(AX) = dst;
1516 	CYCLES(CYCLES_ALU_IMM_ACC);
1517 }
1518 
i386_out_ax_i8()1519 void i386_device::i386_out_ax_i8()         // Opcode 0xe7
1520 {
1521 	uint16_t port = FETCH();
1522 	uint16_t data = REG16(AX);
1523 	WRITEPORT16(port, data);
1524 	CYCLES(CYCLES_OUT_VAR);
1525 }
1526 
i386_out_ax_dx()1527 void i386_device::i386_out_ax_dx()         // Opcode 0xef
1528 {
1529 	uint16_t port = REG16(DX);
1530 	uint16_t data = REG16(AX);
1531 	WRITEPORT16(port, data);
1532 	CYCLES(CYCLES_OUT);
1533 }
1534 
i386_pop_ax()1535 void i386_device::i386_pop_ax()            // Opcode 0x58
1536 {
1537 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1538 	if(i386_limit_check(SS,offset+1) == 0)
1539 		REG16(AX) = POP16();
1540 	else
1541 		FAULT(FAULT_SS,0)
1542 	CYCLES(CYCLES_POP_REG_SHORT);
1543 }
1544 
i386_pop_cx()1545 void i386_device::i386_pop_cx()            // Opcode 0x59
1546 {
1547 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1548 	if(i386_limit_check(SS,offset+1) == 0)
1549 		REG16(CX) = POP16();
1550 	else
1551 		FAULT(FAULT_SS,0)
1552 	CYCLES(CYCLES_POP_REG_SHORT);
1553 }
1554 
i386_pop_dx()1555 void i386_device::i386_pop_dx()            // Opcode 0x5a
1556 {
1557 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1558 	if(i386_limit_check(SS,offset+1) == 0)
1559 		REG16(DX) = POP16();
1560 	else
1561 		FAULT(FAULT_SS,0)
1562 	CYCLES(CYCLES_POP_REG_SHORT);
1563 }
1564 
i386_pop_bx()1565 void i386_device::i386_pop_bx()            // Opcode 0x5b
1566 {
1567 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1568 	if(i386_limit_check(SS,offset+1) == 0)
1569 		REG16(BX) = POP16();
1570 	else
1571 		FAULT(FAULT_SS,0)
1572 	CYCLES(CYCLES_POP_REG_SHORT);
1573 }
1574 
i386_pop_sp()1575 void i386_device::i386_pop_sp()            // Opcode 0x5c
1576 {
1577 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1578 	if(i386_limit_check(SS,offset+1) == 0)
1579 		REG16(SP) = POP16();
1580 	else
1581 		FAULT(FAULT_SS,0)
1582 	CYCLES(CYCLES_POP_REG_SHORT);
1583 }
1584 
i386_pop_bp()1585 void i386_device::i386_pop_bp()            // Opcode 0x5d
1586 {
1587 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1588 	if(i386_limit_check(SS,offset+1) == 0)
1589 		REG16(BP) = POP16();
1590 	else
1591 		FAULT(FAULT_SS,0)
1592 	CYCLES(CYCLES_POP_REG_SHORT);
1593 }
1594 
i386_pop_si()1595 void i386_device::i386_pop_si()            // Opcode 0x5e
1596 {
1597 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1598 	if(i386_limit_check(SS,offset+1) == 0)
1599 		REG16(SI) = POP16();
1600 	else
1601 		FAULT(FAULT_SS,0)
1602 	CYCLES(CYCLES_POP_REG_SHORT);
1603 }
1604 
i386_pop_di()1605 void i386_device::i386_pop_di()            // Opcode 0x5f
1606 {
1607 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1608 	if(i386_limit_check(SS,offset+1) == 0)
1609 		REG16(DI) = POP16();
1610 	else
1611 		FAULT(FAULT_SS,0)
1612 	CYCLES(CYCLES_POP_REG_SHORT);
1613 }
1614 
i386_pop_seg16(int segment)1615 bool i386_device::i386_pop_seg16(int segment)
1616 {
1617 	uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1618 	uint16_t value;
1619 	bool fault;
1620 	if(i386_limit_check(SS,offset+1) == 0)
1621 	{
1622 		ea = i386_translate(SS, offset, 0);
1623 		value = READ16(ea);
1624 		i386_sreg_load(value, segment, &fault);
1625 		if(fault) return false;
1626 		if(STACK_32BIT)
1627 			REG32(ESP) = offset + 2;
1628 		else
1629 			REG16(SP) = offset + 2;
1630 	}
1631 	else
1632 	{
1633 		m_ext = 1;
1634 		i386_trap_with_error(FAULT_SS,0,0,0);
1635 		return false;
1636 	}
1637 	CYCLES(CYCLES_POP_SREG);
1638 	return true;
1639 }
1640 
i386_pop_ds16()1641 void i386_device::i386_pop_ds16()          // Opcode 0x1f
1642 {
1643 	i386_pop_seg16(DS);
1644 }
1645 
i386_pop_es16()1646 void i386_device::i386_pop_es16()          // Opcode 0x07
1647 {
1648 	i386_pop_seg16(ES);
1649 }
1650 
i386_pop_fs16()1651 void i386_device::i386_pop_fs16()          // Opcode 0x0f a1
1652 {
1653 	i386_pop_seg16(FS);
1654 }
1655 
i386_pop_gs16()1656 void i386_device::i386_pop_gs16()          // Opcode 0x0f a9
1657 {
1658 	i386_pop_seg16(GS);
1659 }
1660 
i386_pop_ss16()1661 void i386_device::i386_pop_ss16()          // Opcode 0x17
1662 {
1663 	if(!i386_pop_seg16(SS)) return;
1664 	if(m_IF != 0) // if external interrupts are enabled
1665 	{
1666 		m_IF = 0;  // reset IF for the next instruction
1667 		m_delayed_interrupt_enable = 1;
1668 	}
1669 }
1670 
i386_pop_rm16()1671 void i386_device::i386_pop_rm16()          // Opcode 0x8f
1672 {
1673 	uint8_t modrm = FETCH();
1674 	uint16_t value;
1675 	uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1676 
1677 	if(i386_limit_check(SS,offset+1) == 0)
1678 	{
1679 		uint32_t temp_sp = REG32(ESP);
1680 		value = POP16();
1681 
1682 		if( modrm >= 0xc0 ) {
1683 			STORE_RM16(modrm, value);
1684 		} else {
1685 			try
1686 			{
1687 				ea = GetEA(modrm,1);
1688 				WRITE16(ea, value);
1689 			}
1690 			catch(uint64_t e)
1691 			{
1692 				REG32(ESP) = temp_sp;
1693 				throw e;
1694 			}
1695 		}
1696 	}
1697 	else
1698 		FAULT(FAULT_SS,0)
1699 	CYCLES(CYCLES_POP_RM);
1700 }
1701 
i386_popa()1702 void i386_device::i386_popa()              // Opcode 0x61
1703 {
1704 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1705 
1706 	if(i386_limit_check(SS,offset+15) == 0)
1707 	{
1708 		REG16(DI) = POP16();
1709 		REG16(SI) = POP16();
1710 		REG16(BP) = POP16();
1711 		REG16(SP) += 2;
1712 		REG16(BX) = POP16();
1713 		REG16(DX) = POP16();
1714 		REG16(CX) = POP16();
1715 		REG16(AX) = POP16();
1716 	}
1717 	else
1718 		FAULT(FAULT_SS,0)
1719 	CYCLES(CYCLES_POPA);
1720 }
1721 
i386_popf()1722 void i386_device::i386_popf()              // Opcode 0x9d
1723 {
1724 	uint32_t value;
1725 	uint32_t current = get_flags();
1726 	uint8_t IOPL = (current >> 12) & 0x03;
1727 	uint32_t mask = 0x7fd5;
1728 	uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP));
1729 
1730 	// IOPL can only change if CPL is 0
1731 	if(m_CPL != 0)
1732 		mask &= ~0x00003000;
1733 
1734 	// IF can only change if CPL is at least as privileged as IOPL
1735 	if(m_CPL > IOPL)
1736 		mask &= ~0x00000200;
1737 
1738 	if(V8086_MODE)
1739 	{
1740 		if(IOPL < 3)
1741 		{
1742 			logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc);
1743 			FAULT(FAULT_GP,0)  // #GP(0)
1744 		}
1745 		mask &= ~0x00003000;  // IOPL cannot be changed while in V8086 mode
1746 	}
1747 
1748 	if(i386_limit_check(SS,offset+1) == 0)
1749 	{
1750 		value = POP16();
1751 		set_flags((current & ~mask) | (value & mask));  // mask out reserved bits
1752 	}
1753 	else
1754 		FAULT(FAULT_SS,0)
1755 	CYCLES(CYCLES_POPF);
1756 
1757 	m_auto_clear_RF = false;
1758 }
1759 
i386_push_ax()1760 void i386_device::i386_push_ax()           // Opcode 0x50
1761 {
1762 	uint32_t offset;
1763 	if(STACK_32BIT)
1764 		offset = REG32(ESP) - 2;
1765 	else
1766 		offset = (REG16(SP) - 2) & 0xffff;
1767 	if(i386_limit_check(SS,offset) == 0)
1768 		PUSH16(REG16(AX) );
1769 	else
1770 		FAULT(FAULT_SS,0)
1771 	CYCLES(CYCLES_PUSH_REG_SHORT);
1772 }
1773 
i386_push_cx()1774 void i386_device::i386_push_cx()           // Opcode 0x51
1775 {
1776 	uint32_t offset;
1777 	if(STACK_32BIT)
1778 		offset = REG32(ESP) - 2;
1779 	else
1780 		offset = (REG16(SP) - 2) & 0xffff;
1781 	if(i386_limit_check(SS,offset) == 0)
1782 		PUSH16(REG16(CX) );
1783 	else
1784 		FAULT(FAULT_SS,0)
1785 	CYCLES(CYCLES_PUSH_REG_SHORT);
1786 }
1787 
i386_push_dx()1788 void i386_device::i386_push_dx()           // Opcode 0x52
1789 {
1790 	uint32_t offset;
1791 	if(STACK_32BIT)
1792 		offset = REG32(ESP) - 2;
1793 	else
1794 		offset = (REG16(SP) - 2) & 0xffff;
1795 	if(i386_limit_check(SS,offset) == 0)
1796 		PUSH16(REG16(DX) );
1797 	else
1798 		FAULT(FAULT_SS,0)
1799 	CYCLES(CYCLES_PUSH_REG_SHORT);
1800 }
1801 
i386_push_bx()1802 void i386_device::i386_push_bx()           // Opcode 0x53
1803 {
1804 	uint32_t offset;
1805 	if(STACK_32BIT)
1806 		offset = REG32(ESP) - 2;
1807 	else
1808 		offset = (REG16(SP) - 2) & 0xffff;
1809 	if(i386_limit_check(SS,offset) == 0)
1810 		PUSH16(REG16(BX) );
1811 	else
1812 		FAULT(FAULT_SS,0)
1813 	CYCLES(CYCLES_PUSH_REG_SHORT);
1814 }
1815 
i386_push_sp()1816 void i386_device::i386_push_sp()           // Opcode 0x54
1817 {
1818 	uint32_t offset;
1819 	if(STACK_32BIT)
1820 		offset = REG32(ESP) - 2;
1821 	else
1822 		offset = (REG16(SP) - 2) & 0xffff;
1823 	if(i386_limit_check(SS,offset) == 0)
1824 		PUSH16(REG16(SP) );
1825 	else
1826 		FAULT(FAULT_SS,0)
1827 	CYCLES(CYCLES_PUSH_REG_SHORT);
1828 }
1829 
i386_push_bp()1830 void i386_device::i386_push_bp()           // Opcode 0x55
1831 {
1832 	uint32_t offset;
1833 	if(STACK_32BIT)
1834 		offset = REG32(ESP) - 2;
1835 	else
1836 		offset = (REG16(SP) - 2) & 0xffff;
1837 	if(i386_limit_check(SS,offset) == 0)
1838 		PUSH16(REG16(BP) );
1839 	else
1840 		FAULT(FAULT_SS,0)
1841 	CYCLES(CYCLES_PUSH_REG_SHORT);
1842 }
1843 
i386_push_si()1844 void i386_device::i386_push_si()           // Opcode 0x56
1845 {
1846 	uint32_t offset;
1847 	if(STACK_32BIT)
1848 		offset = REG32(ESP) - 2;
1849 	else
1850 		offset = (REG16(SP) - 2) & 0xffff;
1851 	if(i386_limit_check(SS,offset) == 0)
1852 		PUSH16(REG16(SI) );
1853 	else
1854 		FAULT(FAULT_SS,0)
1855 	CYCLES(CYCLES_PUSH_REG_SHORT);
1856 }
1857 
i386_push_di()1858 void i386_device::i386_push_di()           // Opcode 0x57
1859 {
1860 	uint32_t offset;
1861 	if(STACK_32BIT)
1862 		offset = REG32(ESP) - 2;
1863 	else
1864 		offset = (REG16(SP) - 2) & 0xffff;
1865 	if(i386_limit_check(SS,offset) == 0)
1866 		PUSH16(REG16(DI) );
1867 	else
1868 		FAULT(FAULT_SS,0)
1869 	CYCLES(CYCLES_PUSH_REG_SHORT);
1870 }
1871 
i386_push_cs16()1872 void i386_device::i386_push_cs16()         // Opcode 0x0e
1873 {
1874 	uint32_t offset;
1875 	if(STACK_32BIT)
1876 		offset = REG32(ESP) - 2;
1877 	else
1878 		offset = (REG16(SP) - 2) & 0xffff;
1879 	if(i386_limit_check(SS,offset) == 0)
1880 		PUSH16(m_sreg[CS].selector );
1881 	else
1882 		FAULT(FAULT_SS,0)
1883 	CYCLES(CYCLES_PUSH_SREG);
1884 }
1885 
i386_push_ds16()1886 void i386_device::i386_push_ds16()         // Opcode 0x1e
1887 {
1888 	uint32_t offset;
1889 	if(STACK_32BIT)
1890 		offset = REG32(ESP) - 2;
1891 	else
1892 		offset = (REG16(SP) - 2) & 0xffff;
1893 	if(i386_limit_check(SS,offset) == 0)
1894 		PUSH16(m_sreg[DS].selector );
1895 	else
1896 		FAULT(FAULT_SS,0)
1897 	CYCLES(CYCLES_PUSH_SREG);
1898 }
1899 
i386_push_es16()1900 void i386_device::i386_push_es16()         // Opcode 0x06
1901 {
1902 	uint32_t offset;
1903 	if(STACK_32BIT)
1904 		offset = REG32(ESP) - 2;
1905 	else
1906 		offset = (REG16(SP) - 2) & 0xffff;
1907 	if(i386_limit_check(SS,offset) == 0)
1908 		PUSH16(m_sreg[ES].selector );
1909 	else
1910 		FAULT(FAULT_SS,0)
1911 	CYCLES(CYCLES_PUSH_SREG);
1912 }
1913 
i386_push_fs16()1914 void i386_device::i386_push_fs16()         // Opcode 0x0f a0
1915 {
1916 	uint32_t offset;
1917 	if(STACK_32BIT)
1918 		offset = REG32(ESP) - 2;
1919 	else
1920 		offset = (REG16(SP) - 2) & 0xffff;
1921 	if(i386_limit_check(SS,offset) == 0)
1922 		PUSH16(m_sreg[FS].selector );
1923 	else
1924 		FAULT(FAULT_SS,0)
1925 	CYCLES(CYCLES_PUSH_SREG);
1926 }
1927 
i386_push_gs16()1928 void i386_device::i386_push_gs16()         // Opcode 0x0f a8
1929 {
1930 	uint32_t offset;
1931 	if(STACK_32BIT)
1932 		offset = REG32(ESP) - 2;
1933 	else
1934 		offset = (REG16(SP) - 2) & 0xffff;
1935 	if(i386_limit_check(SS,offset) == 0)
1936 		PUSH16(m_sreg[GS].selector );
1937 	else
1938 		FAULT(FAULT_SS,0)
1939 	CYCLES(CYCLES_PUSH_SREG);
1940 }
1941 
i386_push_ss16()1942 void i386_device::i386_push_ss16()         // Opcode 0x16
1943 {
1944 	uint32_t offset;
1945 	if(STACK_32BIT)
1946 		offset = REG32(ESP) - 2;
1947 	else
1948 		offset = (REG16(SP) - 2) & 0xffff;
1949 	if(i386_limit_check(SS,offset) == 0)
1950 		PUSH16(m_sreg[SS].selector );
1951 	else
1952 		FAULT(FAULT_SS,0)
1953 	CYCLES(CYCLES_PUSH_SREG);
1954 }
1955 
i386_push_i16()1956 void i386_device::i386_push_i16()          // Opcode 0x68
1957 {
1958 	uint16_t value = FETCH16();
1959 	uint32_t offset;
1960 	if(STACK_32BIT)
1961 		offset = REG32(ESP) - 2;
1962 	else
1963 		offset = (REG16(SP) - 2) & 0xffff;
1964 	if(i386_limit_check(SS,offset) == 0)
1965 		PUSH16(value);
1966 	else
1967 		FAULT(FAULT_SS,0)
1968 	CYCLES(CYCLES_PUSH_IMM);
1969 }
1970 
i386_pusha()1971 void i386_device::i386_pusha()             // Opcode 0x60
1972 {
1973 	uint16_t temp = REG16(SP);
1974 	uint32_t offset;
1975 	if(STACK_32BIT)
1976 		offset = REG32(ESP) - 16;
1977 	else
1978 		offset = (REG16(SP) - 16) & 0xffff;
1979 	if(i386_limit_check(SS,offset) == 0)
1980 	{
1981 		PUSH16(REG16(AX) );
1982 		PUSH16(REG16(CX) );
1983 		PUSH16(REG16(DX) );
1984 		PUSH16(REG16(BX) );
1985 		PUSH16(temp );
1986 		PUSH16(REG16(BP) );
1987 		PUSH16(REG16(SI) );
1988 		PUSH16(REG16(DI) );
1989 	}
1990 	else
1991 		FAULT(FAULT_SS,0)
1992 	CYCLES(CYCLES_PUSHA);
1993 }
1994 
i386_pushf()1995 void i386_device::i386_pushf()             // Opcode 0x9c
1996 {
1997 	uint32_t offset;
1998 	if(STACK_32BIT)
1999 		offset = REG32(ESP) - 2;
2000 	else
2001 		offset = (REG16(SP) - 2) & 0xffff;
2002 	if(i386_limit_check(SS,offset) == 0)
2003 		PUSH16(get_flags() & 0xffff );
2004 	else
2005 		FAULT(FAULT_SS,0)
2006 	CYCLES(CYCLES_PUSHF);
2007 }
2008 
i386_ret_near16_i16()2009 void i386_device::i386_ret_near16_i16()    // Opcode 0xc2
2010 {
2011 	int16_t disp = FETCH16();
2012 	m_eip = POP16();
2013 	REG16(SP) += disp;
2014 	CHANGE_PC(m_eip);
2015 	CYCLES(CYCLES_RET_IMM);        /* TODO: Timing = 10 + m */
2016 }
2017 
i386_ret_near16()2018 void i386_device::i386_ret_near16()        // Opcode 0xc3
2019 {
2020 	m_eip = POP16();
2021 	CHANGE_PC(m_eip);
2022 	CYCLES(CYCLES_RET);        /* TODO: Timing = 10 + m */
2023 }
2024 
i386_sbb_rm16_r16()2025 void i386_device::i386_sbb_rm16_r16()      // Opcode 0x19
2026 {
2027 	uint16_t src, dst;
2028 	uint8_t modrm = FETCH();
2029 	if( modrm >= 0xc0 ) {
2030 		src = LOAD_REG16(modrm);
2031 		dst = LOAD_RM16(modrm);
2032 		dst = SBB16(dst, src, m_CF);
2033 		STORE_RM16(modrm, dst);
2034 		CYCLES(CYCLES_ALU_REG_REG);
2035 	} else {
2036 		uint32_t ea = GetEA(modrm,1);
2037 		src = LOAD_REG16(modrm);
2038 		dst = READ16(ea);
2039 		dst = SBB16(dst, src, m_CF);
2040 		WRITE16(ea, dst);
2041 		CYCLES(CYCLES_ALU_REG_MEM);
2042 	}
2043 }
2044 
i386_sbb_r16_rm16()2045 void i386_device::i386_sbb_r16_rm16()      // Opcode 0x1b
2046 {
2047 	uint16_t src, dst;
2048 	uint8_t modrm = FETCH();
2049 	if( modrm >= 0xc0 ) {
2050 		src = LOAD_RM16(modrm);
2051 		dst = LOAD_REG16(modrm);
2052 		dst = SBB16(dst, src, m_CF);
2053 		STORE_REG16(modrm, dst);
2054 		CYCLES(CYCLES_ALU_REG_REG);
2055 	} else {
2056 		uint32_t ea = GetEA(modrm,0);
2057 		src = READ16(ea);
2058 		dst = LOAD_REG16(modrm);
2059 		dst = SBB16(dst, src, m_CF);
2060 		STORE_REG16(modrm, dst);
2061 		CYCLES(CYCLES_ALU_MEM_REG);
2062 	}
2063 }
2064 
i386_sbb_ax_i16()2065 void i386_device::i386_sbb_ax_i16()        // Opcode 0x1d
2066 {
2067 	uint16_t src, dst;
2068 	src = FETCH16();
2069 	dst = REG16(AX);
2070 	dst = SBB16(dst, src, m_CF);
2071 	REG16(AX) = dst;
2072 	CYCLES(CYCLES_ALU_IMM_ACC);
2073 }
2074 
i386_scasw()2075 void i386_device::i386_scasw()             // Opcode 0xaf
2076 {
2077 	uint32_t eas;
2078 	uint16_t src, dst;
2079 	eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 );
2080 	src = READ16(eas);
2081 	dst = REG16(AX);
2082 	SUB16(dst, src);
2083 	BUMP_DI(2);
2084 	CYCLES(CYCLES_SCAS);
2085 }
2086 
i386_shld16_i8()2087 void i386_device::i386_shld16_i8()         // Opcode 0x0f a4
2088 {
2089 	uint8_t modrm = FETCH();
2090 	if( modrm >= 0xc0 ) {
2091 		uint16_t dst = LOAD_RM16(modrm);
2092 		uint16_t upper = LOAD_REG16(modrm);
2093 		uint8_t shift = FETCH();
2094 		shift &= 31;
2095 		if( shift == 0 ) {
2096 		} else if( shift > 15 ) {
2097 			m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2098 			// ppro and above should be (dst >> (32-shift))
2099 			dst = (upper << (shift-16)) | (upper >> (32-shift));
2100 			m_OF = m_CF ^ (dst >> 15);
2101 			SetSZPF16(dst);
2102 		} else {
2103 			m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2104 			dst = (dst << shift) | (upper >> (16-shift));
2105 			m_OF = m_CF ^ (dst >> 15);
2106 			SetSZPF16(dst);
2107 		}
2108 		STORE_RM16(modrm, dst);
2109 		CYCLES(CYCLES_SHLD_REG);
2110 	} else {
2111 		uint32_t ea = GetEA(modrm,1);
2112 		uint16_t dst = READ16(ea);
2113 		uint16_t upper = LOAD_REG16(modrm);
2114 		uint8_t shift = FETCH();
2115 		shift &= 31;
2116 		if( shift == 0 ) {
2117 		} else if( shift > 15 ) {
2118 			m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2119 			dst = (upper << (shift-16)) | (upper >> (32-shift));
2120 			m_OF = m_CF ^ (dst >> 15);
2121 			SetSZPF16(dst);
2122 		} else {
2123 			m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2124 			dst = (dst << shift) | (upper >> (16-shift));
2125 			m_OF = m_CF ^ (dst >> 15);
2126 			SetSZPF16(dst);
2127 		}
2128 		WRITE16(ea, dst);
2129 		CYCLES(CYCLES_SHLD_MEM);
2130 	}
2131 }
2132 
i386_shld16_cl()2133 void i386_device::i386_shld16_cl()         // Opcode 0x0f a5
2134 {
2135 	uint8_t modrm = FETCH();
2136 	if( modrm >= 0xc0 ) {
2137 		uint16_t dst = LOAD_RM16(modrm);
2138 		uint16_t upper = LOAD_REG16(modrm);
2139 		uint8_t shift = REG8(CL);
2140 		shift &= 31;
2141 		if( shift == 0 ) {
2142 		} else if( shift > 15 ) {
2143 			m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2144 			dst = (upper << (shift-16)) | (upper >> (32-shift));
2145 			m_OF = m_CF ^ (dst >> 15);
2146 			SetSZPF16(dst);
2147 		} else {
2148 			m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2149 			dst = (dst << shift) | (upper >> (16-shift));
2150 			m_OF = m_CF ^ (dst >> 15);
2151 			SetSZPF16(dst);
2152 		}
2153 		STORE_RM16(modrm, dst);
2154 		CYCLES(CYCLES_SHLD_REG);
2155 	} else {
2156 		uint32_t ea = GetEA(modrm,1);
2157 		uint16_t dst = READ16(ea);
2158 		uint16_t upper = LOAD_REG16(modrm);
2159 		uint8_t shift = REG8(CL);
2160 		shift &= 31;
2161 		if( shift == 0 ) {
2162 		} else if( shift > 15 ) {
2163 			m_CF = (upper & (1 << (16-shift))) ? 1 : 0;
2164 			dst = (upper << (shift-16)) | (upper >> (32-shift));
2165 			m_OF = m_CF ^ (dst >> 15);
2166 			SetSZPF16(dst);
2167 		} else {
2168 			m_CF = (dst & (1 << (16-shift))) ? 1 : 0;
2169 			dst = (dst << shift) | (upper >> (16-shift));
2170 			m_OF = m_CF ^ (dst >> 15);
2171 			SetSZPF16(dst);
2172 		}
2173 		WRITE16(ea, dst);
2174 		CYCLES(CYCLES_SHLD_MEM);
2175 	}
2176 }
2177 
i386_shrd16_i8()2178 void i386_device::i386_shrd16_i8()         // Opcode 0x0f ac
2179 {
2180 	uint8_t modrm = FETCH();
2181 	if( modrm >= 0xc0 ) {
2182 		uint16_t dst = LOAD_RM16(modrm);
2183 		uint16_t upper = LOAD_REG16(modrm);
2184 		uint8_t shift = FETCH();
2185 		shift &= 31;
2186 		if( shift == 0) {
2187 		} else if( shift > 15 ) {
2188 			m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2189 			dst = (upper >> (shift-16)) | (upper << (32-shift));
2190 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2191 			SetSZPF16(dst);
2192 		} else {
2193 			m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2194 			dst = (dst >> shift) | (upper << (16-shift));
2195 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2196 			SetSZPF16(dst);
2197 		}
2198 		STORE_RM16(modrm, dst);
2199 		CYCLES(CYCLES_SHRD_REG);
2200 	} else {
2201 		uint32_t ea = GetEA(modrm,1);
2202 		uint16_t dst = READ16(ea);
2203 		uint16_t upper = LOAD_REG16(modrm);
2204 		uint8_t shift = FETCH();
2205 		shift &= 31;
2206 		if( shift == 0) {
2207 		} else if( shift > 15 ) {
2208 			m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2209 			dst = (upper >> (shift-16)) | (upper << (32-shift));
2210 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2211 			SetSZPF16(dst);
2212 		} else {
2213 			m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2214 			dst = (dst >> shift) | (upper << (16-shift));
2215 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2216 			SetSZPF16(dst);
2217 		}
2218 		WRITE16(ea, dst);
2219 		CYCLES(CYCLES_SHRD_MEM);
2220 	}
2221 }
2222 
i386_shrd16_cl()2223 void i386_device::i386_shrd16_cl()         // Opcode 0x0f ad
2224 {
2225 	uint8_t modrm = FETCH();
2226 	if( modrm >= 0xc0 ) {
2227 		uint16_t dst = LOAD_RM16(modrm);
2228 		uint16_t upper = LOAD_REG16(modrm);
2229 		uint8_t shift = REG8(CL);
2230 		shift &= 31;
2231 		if( shift == 0) {
2232 		} else if( shift > 15 ) {
2233 			m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2234 			dst = (upper >> (shift-16)) | (upper << (32-shift));
2235 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2236 			SetSZPF16(dst);
2237 		} else {
2238 			m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2239 			dst = (dst >> shift) | (upper << (16-shift));
2240 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2241 			SetSZPF16(dst);
2242 		}
2243 		STORE_RM16(modrm, dst);
2244 		CYCLES(CYCLES_SHRD_REG);
2245 	} else {
2246 		uint32_t ea = GetEA(modrm,1);
2247 		uint16_t dst = READ16(ea);
2248 		uint16_t upper = LOAD_REG16(modrm);
2249 		uint8_t shift = REG8(CL);
2250 		shift &= 31;
2251 		if( shift == 0) {
2252 		} else if( shift > 15 ) {
2253 			m_CF = (upper & (1 << (shift-1))) ? 1 : 0;
2254 			dst = (upper >> (shift-16)) | (upper << (32-shift));
2255 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2256 			SetSZPF16(dst);
2257 		} else {
2258 			m_CF = (dst & (1 << (shift-1))) ? 1 : 0;
2259 			dst = (dst >> shift) | (upper << (16-shift));
2260 			m_OF = ((dst >> 15) ^ (dst >> 14)) & 1;
2261 			SetSZPF16(dst);
2262 		}
2263 		WRITE16(ea, dst);
2264 		CYCLES(CYCLES_SHRD_MEM);
2265 	}
2266 }
2267 
i386_stosw()2268 void i386_device::i386_stosw()             // Opcode 0xab
2269 {
2270 	uint32_t ead;
2271 	ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 );
2272 	WRITE16(ead, REG16(AX));
2273 	BUMP_DI(2);
2274 	CYCLES(CYCLES_STOS);
2275 }
2276 
i386_sub_rm16_r16()2277 void i386_device::i386_sub_rm16_r16()      // Opcode 0x29
2278 {
2279 	uint16_t src, dst;
2280 	uint8_t modrm = FETCH();
2281 	if( modrm >= 0xc0 ) {
2282 		src = LOAD_REG16(modrm);
2283 		dst = LOAD_RM16(modrm);
2284 		dst = SUB16(dst, src);
2285 		STORE_RM16(modrm, dst);
2286 		CYCLES(CYCLES_ALU_REG_REG);
2287 	} else {
2288 		uint32_t ea = GetEA(modrm,1);
2289 		src = LOAD_REG16(modrm);
2290 		dst = READ16(ea);
2291 		dst = SUB16(dst, src);
2292 		WRITE16(ea, dst);
2293 		CYCLES(CYCLES_ALU_REG_MEM);
2294 	}
2295 }
2296 
i386_sub_r16_rm16()2297 void i386_device::i386_sub_r16_rm16()      // Opcode 0x2b
2298 {
2299 	uint16_t src, dst;
2300 	uint8_t modrm = FETCH();
2301 	if( modrm >= 0xc0 ) {
2302 		src = LOAD_RM16(modrm);
2303 		dst = LOAD_REG16(modrm);
2304 		dst = SUB16(dst, src);
2305 		STORE_REG16(modrm, dst);
2306 		CYCLES(CYCLES_ALU_REG_REG);
2307 	} else {
2308 		uint32_t ea = GetEA(modrm,0);
2309 		src = READ16(ea);
2310 		dst = LOAD_REG16(modrm);
2311 		dst = SUB16(dst, src);
2312 		STORE_REG16(modrm, dst);
2313 		CYCLES(CYCLES_ALU_MEM_REG);
2314 	}
2315 }
2316 
i386_sub_ax_i16()2317 void i386_device::i386_sub_ax_i16()        // Opcode 0x2d
2318 {
2319 	uint16_t src, dst;
2320 	src = FETCH16();
2321 	dst = REG16(AX);
2322 	dst = SUB16(dst, src);
2323 	REG16(AX) = dst;
2324 	CYCLES(CYCLES_ALU_IMM_ACC);
2325 }
2326 
i386_test_ax_i16()2327 void i386_device::i386_test_ax_i16()       // Opcode 0xa9
2328 {
2329 	uint16_t src = FETCH16();
2330 	uint16_t dst = REG16(AX);
2331 	dst = src & dst;
2332 	SetSZPF16(dst);
2333 	m_CF = 0;
2334 	m_OF = 0;
2335 	CYCLES(CYCLES_TEST_IMM_ACC);
2336 }
2337 
i386_test_rm16_r16()2338 void i386_device::i386_test_rm16_r16()     // Opcode 0x85
2339 {
2340 	uint16_t src, dst;
2341 	uint8_t modrm = FETCH();
2342 	if( modrm >= 0xc0 ) {
2343 		src = LOAD_REG16(modrm);
2344 		dst = LOAD_RM16(modrm);
2345 		dst = src & dst;
2346 		SetSZPF16(dst);
2347 		m_CF = 0;
2348 		m_OF = 0;
2349 		CYCLES(CYCLES_TEST_REG_REG);
2350 	} else {
2351 		uint32_t ea = GetEA(modrm,0);
2352 		src = LOAD_REG16(modrm);
2353 		dst = READ16(ea);
2354 		dst = src & dst;
2355 		SetSZPF16(dst);
2356 		m_CF = 0;
2357 		m_OF = 0;
2358 		CYCLES(CYCLES_TEST_REG_MEM);
2359 	}
2360 }
2361 
i386_xchg_ax_cx()2362 void i386_device::i386_xchg_ax_cx()        // Opcode 0x91
2363 {
2364 	uint16_t temp;
2365 	temp = REG16(AX);
2366 	REG16(AX) = REG16(CX);
2367 	REG16(CX) = temp;
2368 	CYCLES(CYCLES_XCHG_REG_REG);
2369 }
2370 
i386_xchg_ax_dx()2371 void i386_device::i386_xchg_ax_dx()        // Opcode 0x92
2372 {
2373 	uint16_t temp;
2374 	temp = REG16(AX);
2375 	REG16(AX) = REG16(DX);
2376 	REG16(DX) = temp;
2377 	CYCLES(CYCLES_XCHG_REG_REG);
2378 }
2379 
i386_xchg_ax_bx()2380 void i386_device::i386_xchg_ax_bx()        // Opcode 0x93
2381 {
2382 	uint16_t temp;
2383 	temp = REG16(AX);
2384 	REG16(AX) = REG16(BX);
2385 	REG16(BX) = temp;
2386 	CYCLES(CYCLES_XCHG_REG_REG);
2387 }
2388 
i386_xchg_ax_sp()2389 void i386_device::i386_xchg_ax_sp()        // Opcode 0x94
2390 {
2391 	uint16_t temp;
2392 	temp = REG16(AX);
2393 	REG16(AX) = REG16(SP);
2394 	REG16(SP) = temp;
2395 	CYCLES(CYCLES_XCHG_REG_REG);
2396 }
2397 
i386_xchg_ax_bp()2398 void i386_device::i386_xchg_ax_bp()        // Opcode 0x95
2399 {
2400 	uint16_t temp;
2401 	temp = REG16(AX);
2402 	REG16(AX) = REG16(BP);
2403 	REG16(BP) = temp;
2404 	CYCLES(CYCLES_XCHG_REG_REG);
2405 }
2406 
i386_xchg_ax_si()2407 void i386_device::i386_xchg_ax_si()        // Opcode 0x96
2408 {
2409 	uint16_t temp;
2410 	temp = REG16(AX);
2411 	REG16(AX) = REG16(SI);
2412 	REG16(SI) = temp;
2413 	CYCLES(CYCLES_XCHG_REG_REG);
2414 }
2415 
i386_xchg_ax_di()2416 void i386_device::i386_xchg_ax_di()        // Opcode 0x97
2417 {
2418 	uint16_t temp;
2419 	temp = REG16(AX);
2420 	REG16(AX) = REG16(DI);
2421 	REG16(DI) = temp;
2422 	CYCLES(CYCLES_XCHG_REG_REG);
2423 }
2424 
i386_xchg_r16_rm16()2425 void i386_device::i386_xchg_r16_rm16()     // Opcode 0x87
2426 {
2427 	uint8_t modrm = FETCH();
2428 	if( modrm >= 0xc0 ) {
2429 		uint16_t src = LOAD_RM16(modrm);
2430 		uint16_t dst = LOAD_REG16(modrm);
2431 		STORE_REG16(modrm, src);
2432 		STORE_RM16(modrm, dst);
2433 		CYCLES(CYCLES_XCHG_REG_REG);
2434 	} else {
2435 		uint32_t ea = GetEA(modrm,1);
2436 		uint16_t src = READ16(ea);
2437 		uint16_t dst = LOAD_REG16(modrm);
2438 		STORE_REG16(modrm, src);
2439 		WRITE16(ea, dst);
2440 		CYCLES(CYCLES_XCHG_REG_MEM);
2441 	}
2442 }
2443 
i386_xor_rm16_r16()2444 void i386_device::i386_xor_rm16_r16()      // Opcode 0x31
2445 {
2446 	uint16_t src, dst;
2447 	uint8_t modrm = FETCH();
2448 	if( modrm >= 0xc0 ) {
2449 		src = LOAD_REG16(modrm);
2450 		dst = LOAD_RM16(modrm);
2451 		dst = XOR16(dst, src);
2452 		STORE_RM16(modrm, dst);
2453 		CYCLES(CYCLES_ALU_REG_REG);
2454 	} else {
2455 		uint32_t ea = GetEA(modrm,1);
2456 		src = LOAD_REG16(modrm);
2457 		dst = READ16(ea);
2458 		dst = XOR16(dst, src);
2459 		WRITE16(ea, dst);
2460 		CYCLES(CYCLES_ALU_REG_MEM);
2461 	}
2462 }
2463 
i386_xor_r16_rm16()2464 void i386_device::i386_xor_r16_rm16()      // Opcode 0x33
2465 {
2466 	uint16_t src, dst;
2467 	uint8_t modrm = FETCH();
2468 	if( modrm >= 0xc0 ) {
2469 		src = LOAD_RM16(modrm);
2470 		dst = LOAD_REG16(modrm);
2471 		dst = XOR16(dst, src);
2472 		STORE_REG16(modrm, dst);
2473 		CYCLES(CYCLES_ALU_REG_REG);
2474 	} else {
2475 		uint32_t ea = GetEA(modrm,0);
2476 		src = READ16(ea);
2477 		dst = LOAD_REG16(modrm);
2478 		dst = XOR16(dst, src);
2479 		STORE_REG16(modrm, dst);
2480 		CYCLES(CYCLES_ALU_MEM_REG);
2481 	}
2482 }
2483 
i386_xor_ax_i16()2484 void i386_device::i386_xor_ax_i16()        // Opcode 0x35
2485 {
2486 	uint16_t src, dst;
2487 	src = FETCH16();
2488 	dst = REG16(AX);
2489 	dst = XOR16(dst, src);
2490 	REG16(AX) = dst;
2491 	CYCLES(CYCLES_ALU_IMM_ACC);
2492 }
2493 
2494 
2495 
i386_group81_16()2496 void i386_device::i386_group81_16()        // Opcode 0x81
2497 {
2498 	uint32_t ea;
2499 	uint16_t src, dst;
2500 	uint8_t modrm = FETCH();
2501 
2502 	switch( (modrm >> 3) & 0x7 )
2503 	{
2504 		case 0:     // ADD Rm16, i16
2505 			if( modrm >= 0xc0 ) {
2506 				dst = LOAD_RM16(modrm);
2507 				src = FETCH16();
2508 				dst = ADD16(dst, src);
2509 				STORE_RM16(modrm, dst);
2510 				CYCLES(CYCLES_ALU_REG_REG);
2511 			} else {
2512 				ea = GetEA(modrm,1);
2513 				dst = READ16(ea);
2514 				src = FETCH16();
2515 				dst = ADD16(dst, src);
2516 				WRITE16(ea, dst);
2517 				CYCLES(CYCLES_ALU_REG_MEM);
2518 			}
2519 			break;
2520 		case 1:     // OR Rm16, i16
2521 			if( modrm >= 0xc0 ) {
2522 				dst = LOAD_RM16(modrm);
2523 				src = FETCH16();
2524 				dst = OR16(dst, src);
2525 				STORE_RM16(modrm, dst);
2526 				CYCLES(CYCLES_ALU_REG_REG);
2527 			} else {
2528 				ea = GetEA(modrm,1);
2529 				dst = READ16(ea);
2530 				src = FETCH16();
2531 				dst = OR16(dst, src);
2532 				WRITE16(ea, dst);
2533 				CYCLES(CYCLES_ALU_REG_MEM);
2534 			}
2535 			break;
2536 		case 2:     // ADC Rm16, i16
2537 			if( modrm >= 0xc0 ) {
2538 				dst = LOAD_RM16(modrm);
2539 				src = FETCH16();
2540 				dst = ADC16(dst, src, m_CF);
2541 				STORE_RM16(modrm, dst);
2542 				CYCLES(CYCLES_ALU_REG_REG);
2543 			} else {
2544 				ea = GetEA(modrm,1);
2545 				dst = READ16(ea);
2546 				src = FETCH16();
2547 				dst = ADC16(dst, src, m_CF);
2548 				WRITE16(ea, dst);
2549 				CYCLES(CYCLES_ALU_REG_MEM);
2550 			}
2551 			break;
2552 		case 3:     // SBB Rm16, i16
2553 			if( modrm >= 0xc0 ) {
2554 				dst = LOAD_RM16(modrm);
2555 				src = FETCH16();
2556 				dst = SBB16(dst, src, m_CF);
2557 				STORE_RM16(modrm, dst);
2558 				CYCLES(CYCLES_ALU_REG_REG);
2559 			} else {
2560 				ea = GetEA(modrm,1);
2561 				dst = READ16(ea);
2562 				src = FETCH16();
2563 				dst = SBB16(dst, src, m_CF);
2564 				WRITE16(ea, dst);
2565 				CYCLES(CYCLES_ALU_REG_MEM);
2566 			}
2567 			break;
2568 		case 4:     // AND Rm16, i16
2569 			if( modrm >= 0xc0 ) {
2570 				dst = LOAD_RM16(modrm);
2571 				src = FETCH16();
2572 				dst = AND16(dst, src);
2573 				STORE_RM16(modrm, dst);
2574 				CYCLES(CYCLES_ALU_REG_REG);
2575 			} else {
2576 				ea = GetEA(modrm,1);
2577 				dst = READ16(ea);
2578 				src = FETCH16();
2579 				dst = AND16(dst, src);
2580 				WRITE16(ea, dst);
2581 				CYCLES(CYCLES_ALU_REG_MEM);
2582 			}
2583 			break;
2584 		case 5:     // SUB Rm16, i16
2585 			if( modrm >= 0xc0 ) {
2586 				dst = LOAD_RM16(modrm);
2587 				src = FETCH16();
2588 				dst = SUB16(dst, src);
2589 				STORE_RM16(modrm, dst);
2590 				CYCLES(CYCLES_ALU_REG_REG);
2591 			} else {
2592 				ea = GetEA(modrm,1);
2593 				dst = READ16(ea);
2594 				src = FETCH16();
2595 				dst = SUB16(dst, src);
2596 				WRITE16(ea, dst);
2597 				CYCLES(CYCLES_ALU_REG_MEM);
2598 			}
2599 			break;
2600 		case 6:     // XOR Rm16, i16
2601 			if( modrm >= 0xc0 ) {
2602 				dst = LOAD_RM16(modrm);
2603 				src = FETCH16();
2604 				dst = XOR16(dst, src);
2605 				STORE_RM16(modrm, dst);
2606 				CYCLES(CYCLES_ALU_REG_REG);
2607 			} else {
2608 				ea = GetEA(modrm,1);
2609 				dst = READ16(ea);
2610 				src = FETCH16();
2611 				dst = XOR16(dst, src);
2612 				WRITE16(ea, dst);
2613 				CYCLES(CYCLES_ALU_REG_MEM);
2614 			}
2615 			break;
2616 		case 7:     // CMP Rm16, i16
2617 			if( modrm >= 0xc0 ) {
2618 				dst = LOAD_RM16(modrm);
2619 				src = FETCH16();
2620 				SUB16(dst, src);
2621 				CYCLES(CYCLES_CMP_REG_REG);
2622 			} else {
2623 				ea = GetEA(modrm,0);
2624 				dst = READ16(ea);
2625 				src = FETCH16();
2626 				SUB16(dst, src);
2627 				CYCLES(CYCLES_CMP_REG_MEM);
2628 			}
2629 			break;
2630 	}
2631 }
2632 
i386_group83_16()2633 void i386_device::i386_group83_16()        // Opcode 0x83
2634 {
2635 	uint32_t ea;
2636 	uint16_t src, dst;
2637 	uint8_t modrm = FETCH();
2638 
2639 	switch( (modrm >> 3) & 0x7 )
2640 	{
2641 		case 0:     // ADD Rm16, i16
2642 			if( modrm >= 0xc0 ) {
2643 				dst = LOAD_RM16(modrm);
2644 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2645 				dst = ADD16(dst, src);
2646 				STORE_RM16(modrm, dst);
2647 				CYCLES(CYCLES_ALU_REG_REG);
2648 			} else {
2649 				ea = GetEA(modrm,1);
2650 				dst = READ16(ea);
2651 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2652 				dst = ADD16(dst, src);
2653 				WRITE16(ea, dst);
2654 				CYCLES(CYCLES_ALU_REG_MEM);
2655 			}
2656 			break;
2657 		case 1:     // OR Rm16, i16
2658 			if( modrm >= 0xc0 ) {
2659 				dst = LOAD_RM16(modrm);
2660 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2661 				dst = OR16(dst, src);
2662 				STORE_RM16(modrm, dst);
2663 				CYCLES(CYCLES_ALU_REG_REG);
2664 			} else {
2665 				ea = GetEA(modrm,1);
2666 				dst = READ16(ea);
2667 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2668 				dst = OR16(dst, src);
2669 				WRITE16(ea, dst);
2670 				CYCLES(CYCLES_ALU_REG_MEM);
2671 			}
2672 			break;
2673 		case 2:     // ADC Rm16, i16
2674 			if( modrm >= 0xc0 ) {
2675 				dst = LOAD_RM16(modrm);
2676 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2677 				dst = ADC16(dst, src, m_CF);
2678 				STORE_RM16(modrm, dst);
2679 				CYCLES(CYCLES_ALU_REG_REG);
2680 			} else {
2681 				ea = GetEA(modrm,1);
2682 				dst = READ16(ea);
2683 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2684 				dst = ADC16(dst, src, m_CF);
2685 				WRITE16(ea, dst);
2686 				CYCLES(CYCLES_ALU_REG_MEM);
2687 			}
2688 			break;
2689 		case 3:     // SBB Rm16, i16
2690 			if( modrm >= 0xc0 ) {
2691 				dst = LOAD_RM16(modrm);
2692 				src = ((uint16_t)(int16_t)(int8_t)FETCH());
2693 				dst = SBB16(dst, src, m_CF);
2694 				STORE_RM16(modrm, dst);
2695 				CYCLES(CYCLES_ALU_REG_REG);
2696 			} else {
2697 				ea = GetEA(modrm,1);
2698 				dst = READ16(ea);
2699 				src = ((uint16_t)(int16_t)(int8_t)FETCH());
2700 				dst = SBB16(dst, src, m_CF);
2701 				WRITE16(ea, dst);
2702 				CYCLES(CYCLES_ALU_REG_MEM);
2703 			}
2704 			break;
2705 		case 4:     // AND Rm16, i16
2706 			if( modrm >= 0xc0 ) {
2707 				dst = LOAD_RM16(modrm);
2708 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2709 				dst = AND16(dst, src);
2710 				STORE_RM16(modrm, dst);
2711 				CYCLES(CYCLES_ALU_REG_REG);
2712 			} else {
2713 				ea = GetEA(modrm,1);
2714 				dst = READ16(ea);
2715 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2716 				dst = AND16(dst, src);
2717 				WRITE16(ea, dst);
2718 				CYCLES(CYCLES_ALU_REG_MEM);
2719 			}
2720 			break;
2721 		case 5:     // SUB Rm16, i16
2722 			if( modrm >= 0xc0 ) {
2723 				dst = LOAD_RM16(modrm);
2724 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2725 				dst = SUB16(dst, src);
2726 				STORE_RM16(modrm, dst);
2727 				CYCLES(CYCLES_ALU_REG_REG);
2728 			} else {
2729 				ea = GetEA(modrm,1);
2730 				dst = READ16(ea);
2731 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2732 				dst = SUB16(dst, src);
2733 				WRITE16(ea, dst);
2734 				CYCLES(CYCLES_ALU_REG_MEM);
2735 			}
2736 			break;
2737 		case 6:     // XOR Rm16, i16
2738 			if( modrm >= 0xc0 ) {
2739 				dst = LOAD_RM16(modrm);
2740 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2741 				dst = XOR16(dst, src);
2742 				STORE_RM16(modrm, dst);
2743 				CYCLES(CYCLES_ALU_REG_REG);
2744 			} else {
2745 				ea = GetEA(modrm,1);
2746 				dst = READ16(ea);
2747 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2748 				dst = XOR16(dst, src);
2749 				WRITE16(ea, dst);
2750 				CYCLES(CYCLES_ALU_REG_MEM);
2751 			}
2752 			break;
2753 		case 7:     // CMP Rm16, i16
2754 			if( modrm >= 0xc0 ) {
2755 				dst = LOAD_RM16(modrm);
2756 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2757 				SUB16(dst, src);
2758 				CYCLES(CYCLES_CMP_REG_REG);
2759 			} else {
2760 				ea = GetEA(modrm,0);
2761 				dst = READ16(ea);
2762 				src = (uint16_t)(int16_t)(int8_t)FETCH();
2763 				SUB16(dst, src);
2764 				CYCLES(CYCLES_CMP_REG_MEM);
2765 			}
2766 			break;
2767 	}
2768 }
2769 
i386_groupC1_16()2770 void i386_device::i386_groupC1_16()        // Opcode 0xc1
2771 {
2772 	uint16_t dst;
2773 	uint8_t modrm = FETCH();
2774 	uint8_t shift;
2775 
2776 	if( modrm >= 0xc0 ) {
2777 		dst = LOAD_RM16(modrm);
2778 		shift = FETCH() & 0x1f;
2779 		dst = i386_shift_rotate16(modrm, dst, shift);
2780 		STORE_RM16(modrm, dst);
2781 	} else {
2782 		uint32_t ea = GetEA(modrm,1);
2783 		dst = READ16(ea);
2784 		shift = FETCH() & 0x1f;
2785 		dst = i386_shift_rotate16(modrm, dst, shift);
2786 		WRITE16(ea, dst);
2787 	}
2788 }
2789 
i386_groupD1_16()2790 void i386_device::i386_groupD1_16()        // Opcode 0xd1
2791 {
2792 	uint16_t dst;
2793 	uint8_t modrm = FETCH();
2794 
2795 	if( modrm >= 0xc0 ) {
2796 		dst = LOAD_RM16(modrm);
2797 		dst = i386_shift_rotate16(modrm, dst, 1);
2798 		STORE_RM16(modrm, dst);
2799 	} else {
2800 		uint32_t ea = GetEA(modrm,1);
2801 		dst = READ16(ea);
2802 		dst = i386_shift_rotate16(modrm, dst, 1);
2803 		WRITE16(ea, dst);
2804 	}
2805 }
2806 
i386_groupD3_16()2807 void i386_device::i386_groupD3_16()        // Opcode 0xd3
2808 {
2809 	uint16_t dst;
2810 	uint8_t modrm = FETCH();
2811 
2812 	if( modrm >= 0xc0 ) {
2813 		dst = LOAD_RM16(modrm);
2814 		dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2815 		STORE_RM16(modrm, dst);
2816 	} else {
2817 		uint32_t ea = GetEA(modrm,1);
2818 		dst = READ16(ea);
2819 		dst = i386_shift_rotate16(modrm, dst, REG8(CL));
2820 		WRITE16(ea, dst);
2821 	}
2822 }
2823 
i386_groupF7_16()2824 void i386_device::i386_groupF7_16()        // Opcode 0xf7
2825 {
2826 	uint8_t modrm = FETCH();
2827 
2828 	switch( (modrm >> 3) & 0x7 )
2829 	{
2830 		case 0:         /* TEST Rm16, i16 */
2831 			if( modrm >= 0xc0 ) {
2832 				uint16_t dst = LOAD_RM16(modrm);
2833 				uint16_t src = FETCH16();
2834 				dst &= src;
2835 				m_CF = m_OF = m_AF = 0;
2836 				SetSZPF16(dst);
2837 				CYCLES(CYCLES_TEST_IMM_REG);
2838 			} else {
2839 				uint32_t ea = GetEA(modrm,0);
2840 				uint16_t dst = READ16(ea);
2841 				uint16_t src = FETCH16();
2842 				dst &= src;
2843 				m_CF = m_OF = m_AF = 0;
2844 				SetSZPF16(dst);
2845 				CYCLES(CYCLES_TEST_IMM_MEM);
2846 			}
2847 			break;
2848 		case 2:         /* NOT Rm16 */
2849 			if( modrm >= 0xc0 ) {
2850 				uint16_t dst = LOAD_RM16(modrm);
2851 				dst = ~dst;
2852 				STORE_RM16(modrm, dst);
2853 				CYCLES(CYCLES_NOT_REG);
2854 			} else {
2855 				uint32_t ea = GetEA(modrm,1);
2856 				uint16_t dst = READ16(ea);
2857 				dst = ~dst;
2858 				WRITE16(ea, dst);
2859 				CYCLES(CYCLES_NOT_MEM);
2860 			}
2861 			break;
2862 		case 3:         /* NEG Rm16 */
2863 			if( modrm >= 0xc0 ) {
2864 				uint16_t dst = LOAD_RM16(modrm);
2865 				dst = SUB16(0, dst );
2866 				STORE_RM16(modrm, dst);
2867 				CYCLES(CYCLES_NEG_REG);
2868 			} else {
2869 				uint32_t ea = GetEA(modrm,1);
2870 				uint16_t dst = READ16(ea);
2871 				dst = SUB16(0, dst );
2872 				WRITE16(ea, dst);
2873 				CYCLES(CYCLES_NEG_MEM);
2874 			}
2875 			break;
2876 		case 4:         /* MUL AX, Rm16 */
2877 			{
2878 				uint32_t result;
2879 				uint16_t src, dst;
2880 				if( modrm >= 0xc0 ) {
2881 					src = LOAD_RM16(modrm);
2882 					CYCLES(CYCLES_MUL16_ACC_REG);      /* TODO: Correct multiply timing */
2883 				} else {
2884 					uint32_t ea = GetEA(modrm,0);
2885 					src = READ16(ea);
2886 					CYCLES(CYCLES_MUL16_ACC_MEM);      /* TODO: Correct multiply timing */
2887 				}
2888 
2889 				dst = REG16(AX);
2890 				result = (uint32_t)src * (uint32_t)dst;
2891 				REG16(DX) = (uint16_t)(result >> 16);
2892 				REG16(AX) = (uint16_t)result;
2893 
2894 				m_CF = m_OF = (REG16(DX) != 0);
2895 			}
2896 			break;
2897 		case 5:         /* IMUL AX, Rm16 */
2898 			{
2899 				int32_t result;
2900 				int32_t src, dst;
2901 				if( modrm >= 0xc0 ) {
2902 					src = (int32_t)(int16_t)LOAD_RM16(modrm);
2903 					CYCLES(CYCLES_IMUL16_ACC_REG);     /* TODO: Correct multiply timing */
2904 				} else {
2905 					uint32_t ea = GetEA(modrm,0);
2906 					src = (int32_t)(int16_t)READ16(ea);
2907 					CYCLES(CYCLES_IMUL16_ACC_MEM);     /* TODO: Correct multiply timing */
2908 				}
2909 
2910 				dst = (int32_t)(int16_t)REG16(AX);
2911 				result = src * dst;
2912 
2913 				REG16(DX) = (uint16_t)(result >> 16);
2914 				REG16(AX) = (uint16_t)result;
2915 
2916 				m_CF = m_OF = !(result == (int32_t)(int16_t)result);
2917 			}
2918 			break;
2919 		case 6:         /* DIV AX, Rm16 */
2920 			{
2921 				uint32_t quotient, remainder, result;
2922 				uint16_t src;
2923 				if( modrm >= 0xc0 ) {
2924 					src = LOAD_RM16(modrm);
2925 					CYCLES(CYCLES_DIV16_ACC_REG);
2926 				} else {
2927 					uint32_t ea = GetEA(modrm,0);
2928 					src = READ16(ea);
2929 					CYCLES(CYCLES_DIV16_ACC_MEM);
2930 				}
2931 
2932 				quotient = ((uint32_t)(REG16(DX)) << 16) | (uint32_t)(REG16(AX));
2933 				if( src ) {
2934 					remainder = quotient % (uint32_t)src;
2935 					result = quotient / (uint32_t)src;
2936 					if( result > 0xffff ) {
2937 						/* TODO: Divide error */
2938 					} else {
2939 						REG16(DX) = (uint16_t)remainder;
2940 						REG16(AX) = (uint16_t)result;
2941 
2942 						// this flag is actually undefined, enable on non-cyrix
2943 						if (m_cpuid_id0 != 0x69727943)
2944 							m_CF = 1;
2945 					}
2946 				} else {
2947 					i386_trap(0, 0, 0);
2948 				}
2949 			}
2950 			break;
2951 		case 7:         /* IDIV AX, Rm16 */
2952 			{
2953 				int32_t quotient, remainder, result;
2954 				uint16_t src;
2955 				if( modrm >= 0xc0 ) {
2956 					src = LOAD_RM16(modrm);
2957 					CYCLES(CYCLES_IDIV16_ACC_REG);
2958 				} else {
2959 					uint32_t ea = GetEA(modrm,0);
2960 					src = READ16(ea);
2961 					CYCLES(CYCLES_IDIV16_ACC_MEM);
2962 				}
2963 
2964 				quotient = (((int32_t)REG16(DX)) << 16) | ((uint32_t)REG16(AX));
2965 				if( src ) {
2966 					remainder = quotient % (int32_t)(int16_t)src;
2967 					result = quotient / (int32_t)(int16_t)src;
2968 					if( result > 0xffff ) {
2969 						/* TODO: Divide error */
2970 					} else {
2971 						REG16(DX) = (uint16_t)remainder;
2972 						REG16(AX) = (uint16_t)result;
2973 
2974 						// this flag is actually undefined, enable on non-cyrix
2975 						if (m_cpuid_id0 != 0x69727943)
2976 							m_CF = 1;
2977 					}
2978 				} else {
2979 					i386_trap(0, 0, 0);
2980 				}
2981 			}
2982 			break;
2983 	}
2984 }
2985 
i386_groupFF_16()2986 void i386_device::i386_groupFF_16()        // Opcode 0xff
2987 {
2988 	uint8_t modrm = FETCH();
2989 
2990 	switch( (modrm >> 3) & 0x7 )
2991 	{
2992 		case 0:         /* INC Rm16 */
2993 			if( modrm >= 0xc0 ) {
2994 				uint16_t dst = LOAD_RM16(modrm);
2995 				dst = INC16(dst);
2996 				STORE_RM16(modrm, dst);
2997 				CYCLES(CYCLES_INC_REG);
2998 			} else {
2999 				uint32_t ea = GetEA(modrm,1);
3000 				uint16_t dst = READ16(ea);
3001 				dst = INC16(dst);
3002 				WRITE16(ea, dst);
3003 				CYCLES(CYCLES_INC_MEM);
3004 			}
3005 			break;
3006 		case 1:         /* DEC Rm16 */
3007 			if( modrm >= 0xc0 ) {
3008 				uint16_t dst = LOAD_RM16(modrm);
3009 				dst = DEC16(dst);
3010 				STORE_RM16(modrm, dst);
3011 				CYCLES(CYCLES_DEC_REG);
3012 			} else {
3013 				uint32_t ea = GetEA(modrm,1);
3014 				uint16_t dst = READ16(ea);
3015 				dst = DEC16(dst);
3016 				WRITE16(ea, dst);
3017 				CYCLES(CYCLES_DEC_MEM);
3018 			}
3019 			break;
3020 		case 2:         /* CALL Rm16 */
3021 			{
3022 				uint16_t address;
3023 				if( modrm >= 0xc0 ) {
3024 					address = LOAD_RM16(modrm);
3025 					CYCLES(CYCLES_CALL_REG);       /* TODO: Timing = 7 + m */
3026 				} else {
3027 					uint32_t ea = GetEA(modrm,0);
3028 					address = READ16(ea);
3029 					CYCLES(CYCLES_CALL_MEM);       /* TODO: Timing = 10 + m */
3030 				}
3031 				PUSH16(m_eip );
3032 				m_eip = address;
3033 				CHANGE_PC(m_eip);
3034 			}
3035 			break;
3036 		case 3:         /* CALL FAR Rm16 */
3037 			{
3038 				uint16_t address, selector;
3039 				if( modrm >= 0xc0 )
3040 				{
3041 					report_invalid_modrm("groupFF_16", modrm);
3042 				}
3043 				else
3044 				{
3045 					uint32_t ea = GetEA(modrm,0);
3046 					address = READ16(ea + 0);
3047 					selector = READ16(ea + 2);
3048 					CYCLES(CYCLES_CALL_MEM_INTERSEG);      /* TODO: Timing = 10 + m */
3049 
3050 					if(PROTECTED_MODE && !V8086_MODE)
3051 					{
3052 						i386_protected_mode_call(selector,address,1,0);
3053 					}
3054 					else
3055 					{
3056 						PUSH16(m_sreg[CS].selector );
3057 						PUSH16(m_eip );
3058 						m_sreg[CS].selector = selector;
3059 						m_performed_intersegment_jump = 1;
3060 						i386_load_segment_descriptor(CS );
3061 						m_eip = address;
3062 						CHANGE_PC(m_eip);
3063 					}
3064 				}
3065 			}
3066 			break;
3067 		case 4:         /* JMP Rm16 */
3068 			{
3069 				uint16_t address;
3070 				if( modrm >= 0xc0 ) {
3071 					address = LOAD_RM16(modrm);
3072 					CYCLES(CYCLES_JMP_REG);        /* TODO: Timing = 7 + m */
3073 				} else {
3074 					uint32_t ea = GetEA(modrm,0);
3075 					address = READ16(ea);
3076 					CYCLES(CYCLES_JMP_MEM);        /* TODO: Timing = 10 + m */
3077 				}
3078 				m_eip = address;
3079 				CHANGE_PC(m_eip);
3080 			}
3081 			break;
3082 		case 5:         /* JMP FAR Rm16 */
3083 			{
3084 				uint16_t address, selector;
3085 
3086 				if( modrm >= 0xc0 )
3087 				{
3088 					report_invalid_modrm("groupFF_16", modrm);
3089 				}
3090 				else
3091 				{
3092 					uint32_t ea = GetEA(modrm,0);
3093 					address = READ16(ea + 0);
3094 					selector = READ16(ea + 2);
3095 					CYCLES(CYCLES_JMP_MEM_INTERSEG);       /* TODO: Timing = 10 + m */
3096 					if(PROTECTED_MODE && !V8086_MODE)
3097 					{
3098 						i386_protected_mode_jump(selector,address,1,0);
3099 					}
3100 					else
3101 					{
3102 						m_sreg[CS].selector = selector;
3103 						m_performed_intersegment_jump = 1;
3104 						i386_load_segment_descriptor(CS );
3105 						m_eip = address;
3106 						CHANGE_PC(m_eip);
3107 					}
3108 				}
3109 			}
3110 			break;
3111 		case 6:         /* PUSH Rm16 */
3112 			{
3113 				uint16_t value;
3114 				if( modrm >= 0xc0 ) {
3115 					value = LOAD_RM16(modrm);
3116 				} else {
3117 					uint32_t ea = GetEA(modrm,0);
3118 					value = READ16(ea);
3119 				}
3120 				PUSH16(value);
3121 				CYCLES(CYCLES_PUSH_RM);
3122 			}
3123 			break;
3124 		default:
3125 			report_invalid_modrm("groupFF_16", modrm);
3126 			break;
3127 	}
3128 }
3129 
i386_group0F00_16()3130 void i386_device::i386_group0F00_16()          // Opcode 0x0f 00
3131 {
3132 	uint32_t address, ea;
3133 	uint8_t modrm = FETCH();
3134 	I386_SREG seg;
3135 	uint8_t result;
3136 
3137 	switch( (modrm >> 3) & 0x7 )
3138 	{
3139 		case 0:         /* SLDT */
3140 			if ( PROTECTED_MODE && !V8086_MODE )
3141 			{
3142 				if( modrm >= 0xc0 ) {
3143 					STORE_RM16(modrm, m_ldtr.segment);
3144 					CYCLES(CYCLES_SLDT_REG);
3145 				} else {
3146 					ea = GetEA(modrm,1);
3147 					WRITE16(ea, m_ldtr.segment);
3148 					CYCLES(CYCLES_SLDT_MEM);
3149 				}
3150 			}
3151 			else
3152 			{
3153 				i386_trap(6, 0, 0);
3154 			}
3155 			break;
3156 		case 1:         /* STR */
3157 			if ( PROTECTED_MODE && !V8086_MODE )
3158 			{
3159 				if( modrm >= 0xc0 ) {
3160 					STORE_RM16(modrm, m_task.segment);
3161 					CYCLES(CYCLES_STR_REG);
3162 				} else {
3163 					ea = GetEA(modrm,1);
3164 					WRITE16(ea, m_task.segment);
3165 					CYCLES(CYCLES_STR_MEM);
3166 				}
3167 			}
3168 			else
3169 			{
3170 				i386_trap(6, 0, 0);
3171 			}
3172 			break;
3173 		case 2:         /* LLDT */
3174 			if ( PROTECTED_MODE && !V8086_MODE )
3175 			{
3176 				if(m_CPL)
3177 					FAULT(FAULT_GP,0)
3178 				if( modrm >= 0xc0 ) {
3179 					address = LOAD_RM16(modrm);
3180 					m_ldtr.segment = address;
3181 					CYCLES(CYCLES_LLDT_REG);
3182 				} else {
3183 					ea = GetEA(modrm,0);
3184 					m_ldtr.segment = READ16(ea);
3185 					CYCLES(CYCLES_LLDT_MEM);
3186 				}
3187 				memset(&seg, 0, sizeof(seg));
3188 				seg.selector = m_ldtr.segment;
3189 				i386_load_protected_mode_segment(&seg,nullptr);
3190 				m_ldtr.limit = seg.limit;
3191 				m_ldtr.base = seg.base;
3192 				m_ldtr.flags = seg.flags;
3193 			}
3194 			else
3195 			{
3196 				i386_trap(6, 0, 0);
3197 			}
3198 			break;
3199 
3200 		case 3:         /* LTR */
3201 			if ( PROTECTED_MODE && !V8086_MODE )
3202 			{
3203 				if(m_CPL)
3204 					FAULT(FAULT_GP,0)
3205 				if( modrm >= 0xc0 ) {
3206 					address = LOAD_RM16(modrm);
3207 					m_task.segment = address;
3208 					CYCLES(CYCLES_LTR_REG);
3209 				} else {
3210 					ea = GetEA(modrm,0);
3211 					m_task.segment = READ16(ea);
3212 					CYCLES(CYCLES_LTR_MEM);
3213 				}
3214 				memset(&seg, 0, sizeof(seg));
3215 				seg.selector = m_task.segment;
3216 				i386_load_protected_mode_segment(&seg,nullptr);
3217 
3218 				uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5;
3219 				i386_translate_address(TRANSLATE_READ, &addr, nullptr);
3220 				m_program->write_byte(addr, (seg.flags & 0xff) | 2);
3221 
3222 				m_task.limit = seg.limit;
3223 				m_task.base = seg.base;
3224 				m_task.flags = seg.flags | 2;
3225 			}
3226 			else
3227 			{
3228 				i386_trap(6, 0, 0);
3229 			}
3230 			break;
3231 
3232 		case 4:  /* VERR */
3233 			if ( PROTECTED_MODE && !V8086_MODE )
3234 			{
3235 				result = 1;
3236 				if( modrm >= 0xc0 ) {
3237 					address = LOAD_RM16(modrm);
3238 					CYCLES(CYCLES_VERR_REG);
3239 				} else {
3240 					ea = GetEA(modrm,0);
3241 					address = READ16(ea);
3242 					CYCLES(CYCLES_VERR_MEM);
3243 				}
3244 				memset(&seg, 0, sizeof(seg));
3245 				seg.selector = address;
3246 				result = i386_load_protected_mode_segment(&seg,nullptr);
3247 				// check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3248 				if(!(seg.flags & 0x10))
3249 					result = 0;
3250 				// check that the segment is readable
3251 				if(seg.flags & 0x10)  // is code or data segment
3252 				{
3253 					if(seg.flags & 0x08)  // is code segment, so check if it's readable
3254 					{
3255 						if(!(seg.flags & 0x02))
3256 						{
3257 							result = 0;
3258 						}
3259 						else
3260 						{  // check if conforming, these are always readable, regardless of privilege
3261 							if(!(seg.flags & 0x04))
3262 							{
3263 								// if not conforming, then we must check privilege levels (TODO: current privilege level check)
3264 								if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3265 									result = 0;
3266 							}
3267 						}
3268 					}
3269 				}
3270 				// check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3271 				SetZF(result);
3272 			}
3273 			else
3274 			{
3275 				i386_trap(6, 0, 0);
3276 				logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n");
3277 			}
3278 			break;
3279 
3280 		case 5:  /* VERW */
3281 			if ( PROTECTED_MODE && !V8086_MODE )
3282 			{
3283 				result = 1;
3284 				if( modrm >= 0xc0 ) {
3285 					address = LOAD_RM16(modrm);
3286 					CYCLES(CYCLES_VERW_REG);
3287 				} else {
3288 					ea = GetEA(modrm,0);
3289 					address = READ16(ea);
3290 					CYCLES(CYCLES_VERW_MEM);
3291 				}
3292 				memset(&seg, 0, sizeof(seg));
3293 				seg.selector = address;
3294 				result = i386_load_protected_mode_segment(&seg,nullptr);
3295 				// check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...)
3296 				if(!(seg.flags & 0x10))
3297 					result = 0;
3298 				// check that the segment is writable
3299 				if(seg.flags & 0x10)  // is code or data segment
3300 				{
3301 					if(seg.flags & 0x08)  // is code segment (and thus, not writable)
3302 					{
3303 						result = 0;
3304 					}
3305 					else
3306 					{  // is data segment
3307 						if(!(seg.flags & 0x02))
3308 							result = 0;
3309 					}
3310 				}
3311 				// check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO)
3312 				if(((seg.flags >> 5) & 0x03) < (address & 0x03))
3313 					result = 0;
3314 				SetZF(result);
3315 			}
3316 			else
3317 			{
3318 				i386_trap(6, 0, 0);
3319 				logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n");
3320 			}
3321 			break;
3322 
3323 		default:
3324 			report_invalid_modrm("group0F00_16", modrm);
3325 			break;
3326 	}
3327 }
3328 
i386_group0F01_16()3329 void i386_device::i386_group0F01_16()      // Opcode 0x0f 01
3330 {
3331 	uint8_t modrm = FETCH();
3332 	uint16_t address;
3333 	uint32_t ea;
3334 
3335 	switch( (modrm >> 3) & 0x7 )
3336 	{
3337 		case 0:         /* SGDT */
3338 			{
3339 				if( modrm >= 0xc0 ) {
3340 					address = LOAD_RM16(modrm);
3341 					ea = i386_translate(CS, address, 1 );
3342 				} else {
3343 					ea = GetEA(modrm,1);
3344 				}
3345 				WRITE16(ea, m_gdtr.limit);
3346 				WRITE32(ea + 2, m_gdtr.base);
3347 				CYCLES(CYCLES_SGDT);
3348 				break;
3349 			}
3350 		case 1:         /* SIDT */
3351 			{
3352 				if (modrm >= 0xc0)
3353 				{
3354 					address = LOAD_RM16(modrm);
3355 					ea = i386_translate(CS, address, 1 );
3356 				}
3357 				else
3358 				{
3359 					ea = GetEA(modrm,1);
3360 				}
3361 				WRITE16(ea, m_idtr.limit);
3362 				WRITE32(ea + 2, m_idtr.base);
3363 				CYCLES(CYCLES_SIDT);
3364 				break;
3365 			}
3366 		case 2:         /* LGDT */
3367 			{
3368 				if(PROTECTED_MODE && m_CPL)
3369 					FAULT(FAULT_GP,0)
3370 				if( modrm >= 0xc0 ) {
3371 					address = LOAD_RM16(modrm);
3372 					ea = i386_translate(CS, address, 0 );
3373 				} else {
3374 					ea = GetEA(modrm,0);
3375 				}
3376 				m_gdtr.limit = READ16(ea);
3377 				m_gdtr.base = READ32(ea + 2) & 0xffffff;
3378 				CYCLES(CYCLES_LGDT);
3379 				break;
3380 			}
3381 		case 3:         /* LIDT */
3382 			{
3383 				if(PROTECTED_MODE && m_CPL)
3384 					FAULT(FAULT_GP,0)
3385 				if( modrm >= 0xc0 ) {
3386 					address = LOAD_RM16(modrm);
3387 					ea = i386_translate(CS, address, 0 );
3388 				} else {
3389 					ea = GetEA(modrm,0);
3390 				}
3391 				m_idtr.limit = READ16(ea);
3392 				m_idtr.base = READ32(ea + 2) & 0xffffff;
3393 				CYCLES(CYCLES_LIDT);
3394 				break;
3395 			}
3396 		case 4:         /* SMSW */
3397 			{
3398 				if( modrm >= 0xc0 ) {
3399 					STORE_RM16(modrm, m_cr[0]);
3400 					CYCLES(CYCLES_SMSW_REG);
3401 				} else {
3402 					ea = GetEA(modrm,1);
3403 					WRITE16(ea, m_cr[0]);
3404 					CYCLES(CYCLES_SMSW_MEM);
3405 				}
3406 				break;
3407 			}
3408 		case 6:         /* LMSW */
3409 			{
3410 				if(PROTECTED_MODE && m_CPL)
3411 					FAULT(FAULT_GP,0)
3412 				uint16_t b;
3413 				if( modrm >= 0xc0 ) {
3414 					b = LOAD_RM16(modrm);
3415 					CYCLES(CYCLES_LMSW_REG);
3416 				} else {
3417 					ea = GetEA(modrm,0);
3418 					CYCLES(CYCLES_LMSW_MEM);
3419 				b = READ16(ea);
3420 				}
3421 				if(PROTECTED_MODE)
3422 					b |= 0x0001;  // cannot return to real mode using this instruction.
3423 				m_cr[0] &= ~0x0000000f;
3424 				m_cr[0] |= b & 0x0000000f;
3425 				break;
3426 			}
3427 		default:
3428 			report_invalid_modrm("group0F01_16", modrm);
3429 			break;
3430 	}
3431 }
3432 
i386_group0FBA_16()3433 void i386_device::i386_group0FBA_16()      // Opcode 0x0f ba
3434 {
3435 	uint8_t modrm = FETCH();
3436 
3437 	switch( (modrm >> 3) & 0x7 )
3438 	{
3439 		case 4:         /* BT Rm16, i8 */
3440 			if( modrm >= 0xc0 ) {
3441 				uint16_t dst = LOAD_RM16(modrm);
3442 				uint8_t bit = FETCH();
3443 
3444 				if( dst & (1 << bit) )
3445 					m_CF = 1;
3446 				else
3447 					m_CF = 0;
3448 
3449 				CYCLES(CYCLES_BT_IMM_REG);
3450 			} else {
3451 				uint32_t ea = GetEA(modrm,0);
3452 				uint16_t dst = READ16(ea);
3453 				uint8_t bit = FETCH();
3454 
3455 				if( dst & (1 << bit) )
3456 					m_CF = 1;
3457 				else
3458 					m_CF = 0;
3459 
3460 				CYCLES(CYCLES_BT_IMM_MEM);
3461 			}
3462 			break;
3463 		case 5:         /* BTS Rm16, i8 */
3464 			if( modrm >= 0xc0 ) {
3465 				uint16_t dst = LOAD_RM16(modrm);
3466 				uint8_t bit = FETCH();
3467 
3468 				if( dst & (1 << bit) )
3469 					m_CF = 1;
3470 				else
3471 					m_CF = 0;
3472 				dst |= (1 << bit);
3473 
3474 				STORE_RM16(modrm, dst);
3475 				CYCLES(CYCLES_BTS_IMM_REG);
3476 			} else {
3477 				uint32_t ea = GetEA(modrm,1);
3478 				uint16_t dst = READ16(ea);
3479 				uint8_t bit = FETCH();
3480 
3481 				if( dst & (1 << bit) )
3482 					m_CF = 1;
3483 				else
3484 					m_CF = 0;
3485 				dst |= (1 << bit);
3486 
3487 				WRITE16(ea, dst);
3488 				CYCLES(CYCLES_BTS_IMM_MEM);
3489 			}
3490 			break;
3491 		case 6:         /* BTR Rm16, i8 */
3492 			if( modrm >= 0xc0 ) {
3493 				uint16_t dst = LOAD_RM16(modrm);
3494 				uint8_t bit = FETCH();
3495 
3496 				if( dst & (1 << bit) )
3497 					m_CF = 1;
3498 				else
3499 					m_CF = 0;
3500 				dst &= ~(1 << bit);
3501 
3502 				STORE_RM16(modrm, dst);
3503 				CYCLES(CYCLES_BTR_IMM_REG);
3504 			} else {
3505 				uint32_t ea = GetEA(modrm,1);
3506 				uint16_t dst = READ16(ea);
3507 				uint8_t bit = FETCH();
3508 
3509 				if( dst & (1 << bit) )
3510 					m_CF = 1;
3511 				else
3512 					m_CF = 0;
3513 				dst &= ~(1 << bit);
3514 
3515 				WRITE16(ea, dst);
3516 				CYCLES(CYCLES_BTR_IMM_MEM);
3517 			}
3518 			break;
3519 		case 7:         /* BTC Rm16, i8 */
3520 			if( modrm >= 0xc0 ) {
3521 				uint16_t dst = LOAD_RM16(modrm);
3522 				uint8_t bit = FETCH();
3523 
3524 				if( dst & (1 << bit) )
3525 					m_CF = 1;
3526 				else
3527 					m_CF = 0;
3528 				dst ^= (1 << bit);
3529 
3530 				STORE_RM16(modrm, dst);
3531 				CYCLES(CYCLES_BTC_IMM_REG);
3532 			} else {
3533 				uint32_t ea = GetEA(modrm,1);
3534 				uint16_t dst = READ16(ea);
3535 				uint8_t bit = FETCH();
3536 
3537 				if( dst & (1 << bit) )
3538 					m_CF = 1;
3539 				else
3540 					m_CF = 0;
3541 				dst ^= (1 << bit);
3542 
3543 				WRITE16(ea, dst);
3544 				CYCLES(CYCLES_BTC_IMM_MEM);
3545 			}
3546 			break;
3547 		default:
3548 			report_invalid_modrm("group0FBA_16", modrm);
3549 			break;
3550 	}
3551 }
3552 
i386_lar_r16_rm16()3553 void i386_device::i386_lar_r16_rm16()  // Opcode 0x0f 0x02
3554 {
3555 	uint8_t modrm = FETCH();
3556 	I386_SREG seg;
3557 	uint8_t type;
3558 
3559 	if(PROTECTED_MODE && !V8086_MODE)
3560 	{
3561 		memset(&seg,0,sizeof(seg));
3562 		if(modrm >= 0xc0)
3563 		{
3564 			seg.selector = LOAD_RM16(modrm);
3565 			CYCLES(CYCLES_LAR_REG);
3566 		}
3567 		else
3568 		{
3569 			uint32_t ea = GetEA(modrm,0);
3570 			seg.selector = READ16(ea);
3571 			CYCLES(CYCLES_LAR_MEM);
3572 		}
3573 		if(seg.selector == 0)
3574 		{
3575 			SetZF(0);  // not a valid segment
3576 		//  logerror("i386 (%08x): LAR: Selector %04x is invalid type.\n",m_pc,seg.selector);
3577 		}
3578 		else
3579 		{
3580 			if(!i386_load_protected_mode_segment(&seg,nullptr))
3581 			{
3582 				SetZF(0);
3583 				return;
3584 			}
3585 			uint8_t DPL = (seg.flags >> 5) & 3;
3586 			if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3587 			{
3588 				SetZF(0);
3589 				return;
3590 			}
3591 			if(!(seg.flags & 0x10))  // special segment
3592 			{
3593 				// check for invalid segment types
3594 				type = seg.flags & 0x000f;
3595 				if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d)
3596 				{
3597 					SetZF(0);  // invalid segment type
3598 				}
3599 				else
3600 				{
3601 					STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3602 					SetZF(1);
3603 				}
3604 			}
3605 			else
3606 			{  // data or code segment (both are valid for LAR)
3607 				STORE_REG16(modrm,(seg.flags << 8) & 0xff00);
3608 				SetZF(1);
3609 			}
3610 		}
3611 	}
3612 	else
3613 	{
3614 		// illegal opcode
3615 		i386_trap(6,0, 0);
3616 		logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n");
3617 	}
3618 }
3619 
i386_lsl_r16_rm16()3620 void i386_device::i386_lsl_r16_rm16()  // Opcode 0x0f 0x03
3621 {
3622 	uint8_t modrm = FETCH();
3623 	uint32_t limit;
3624 	I386_SREG seg;
3625 
3626 	if(PROTECTED_MODE && !V8086_MODE)
3627 	{
3628 		memset(&seg, 0, sizeof(seg));
3629 		if(modrm >= 0xc0)
3630 		{
3631 			seg.selector = LOAD_RM16(modrm);
3632 		}
3633 		else
3634 		{
3635 			uint32_t ea = GetEA(modrm,0);
3636 			seg.selector = READ16(ea);
3637 		}
3638 		if(seg.selector == 0)
3639 		{
3640 			SetZF(0);  // not a valid segment
3641 		}
3642 		else
3643 		{
3644 			uint8_t type;
3645 			if(!i386_load_protected_mode_segment(&seg,nullptr))
3646 			{
3647 				SetZF(0);
3648 				return;
3649 			}
3650 			uint8_t DPL = (seg.flags >> 5) & 3;
3651 			if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
3652 			{
3653 				SetZF(0);
3654 				return;
3655 			}
3656 			type = seg.flags & 0x1f;
3657 			switch(type)
3658 			{
3659 			case 0:
3660 			case 4:
3661 			case 5:
3662 			case 6:
3663 			case 7:
3664 			case 8:
3665 			case 10:
3666 			case 12:
3667 			case 13:
3668 			case 14:
3669 			case 15:
3670 				SetZF(0);
3671 				return;
3672 			default:
3673 				limit = seg.limit;
3674 				STORE_REG16(modrm,limit & 0x0000ffff);
3675 				SetZF(1);
3676 			}
3677 		}
3678 	}
3679 	else
3680 		i386_trap(6, 0, 0);
3681 }
3682 
i386_bound_r16_m16_m16()3683 void i386_device::i386_bound_r16_m16_m16() // Opcode 0x62
3684 {
3685 	uint8_t modrm;
3686 	int16_t val, low, high;
3687 
3688 	modrm = FETCH();
3689 
3690 	if (modrm >= 0xc0)
3691 	{
3692 		low = high = LOAD_RM16(modrm);
3693 	}
3694 	else
3695 	{
3696 		uint32_t ea = GetEA(modrm,0);
3697 		low = READ16(ea + 0);
3698 		high = READ16(ea + 2);
3699 	}
3700 	val = LOAD_REG16(modrm);
3701 
3702 	if ((val < low) || (val > high))
3703 	{
3704 		CYCLES(CYCLES_BOUND_OUT_RANGE);
3705 		i386_trap(5, 0, 0);
3706 	}
3707 	else
3708 	{
3709 		CYCLES(CYCLES_BOUND_IN_RANGE);
3710 	}
3711 }
3712 
i386_retf16()3713 void i386_device::i386_retf16()            // Opcode 0xcb
3714 {
3715 	if(PROTECTED_MODE && !V8086_MODE)
3716 	{
3717 		i386_protected_mode_retf(0,0);
3718 	}
3719 	else
3720 	{
3721 		m_eip = POP16();
3722 		m_sreg[CS].selector = POP16();
3723 		i386_load_segment_descriptor(CS );
3724 		CHANGE_PC(m_eip);
3725 	}
3726 
3727 	CYCLES(CYCLES_RET_INTERSEG);
3728 }
3729 
i386_retf_i16()3730 void i386_device::i386_retf_i16()          // Opcode 0xca
3731 {
3732 	uint16_t count = FETCH16();
3733 
3734 	if(PROTECTED_MODE && !V8086_MODE)
3735 	{
3736 		i386_protected_mode_retf(count,0);
3737 	}
3738 	else
3739 	{
3740 		m_eip = POP16();
3741 		m_sreg[CS].selector = POP16();
3742 		i386_load_segment_descriptor(CS );
3743 		CHANGE_PC(m_eip);
3744 		REG16(SP) += count;
3745 	}
3746 
3747 	CYCLES(CYCLES_RET_IMM_INTERSEG);
3748 }
3749 
i386_load_far_pointer16(int s)3750 bool i386_device::i386_load_far_pointer16(int s)
3751 {
3752 	uint8_t modrm = FETCH();
3753 	uint16_t selector;
3754 
3755 	if( modrm >= 0xc0 ) {
3756 		//logerror("i386: load_far_pointer16 NYI\n"); // don't log, NT will use this a lot
3757 		i386_trap(6, 0, 0);
3758 		return false;
3759 	} else {
3760 		uint32_t ea = GetEA(modrm,0);
3761 		STORE_REG16(modrm, READ16(ea + 0));
3762 		selector = READ16(ea + 2);
3763 		i386_sreg_load(selector,s,nullptr);
3764 	}
3765 	return true;
3766 }
3767 
i386_lds16()3768 void i386_device::i386_lds16()             // Opcode 0xc5
3769 {
3770 	if(i386_load_far_pointer16(DS))
3771 		CYCLES(CYCLES_LDS);
3772 }
3773 
i386_lss16()3774 void i386_device::i386_lss16()             // Opcode 0x0f 0xb2
3775 {
3776 	if(i386_load_far_pointer16(SS))
3777 		CYCLES(CYCLES_LSS);
3778 }
3779 
i386_les16()3780 void i386_device::i386_les16()             // Opcode 0xc4
3781 {
3782 	if(i386_load_far_pointer16(ES))
3783 		CYCLES(CYCLES_LES);
3784 }
3785 
i386_lfs16()3786 void i386_device::i386_lfs16()             // Opcode 0x0f 0xb4
3787 {
3788 	if(i386_load_far_pointer16(FS))
3789 		CYCLES(CYCLES_LFS);
3790 }
3791 
i386_lgs16()3792 void i386_device::i386_lgs16()             // Opcode 0x0f 0xb5
3793 {
3794 	if(i386_load_far_pointer16(GS))
3795 		CYCLES(CYCLES_LGS);
3796 }
3797