1 // license:BSD-3-Clause
2 // copyright-holders:Carl
3 #include "i86.h"
4 
5 #define CF      (m_CarryVal!=0)
6 #define SF      (m_SignVal<0)
7 #define ZF      (m_ZeroVal==0)
8 #define PF      m_parity_table[(uint8_t)m_ParityVal]
9 #define AF      (m_AuxVal!=0)
10 #define OF      (m_OverVal!=0)
11 
12 /* The interrupt number of a pending external interrupt pending NMI is 2.   */
13 /* For INTR interrupts, the level is caught on the bus during an INTA cycle */
14 
15 #define INT_IRQ 0x01
16 #define NMI_IRQ 0x02
17 
fetch_word()18 inline uint16_t i8086_common_cpu_device::fetch_word()
19 {
20 	uint16_t data = fetch();
21 	data |= ( fetch() << 8 );
22 	return data;
23 }
24 
repx_op()25 inline uint8_t i8086_common_cpu_device::repx_op()
26 {
27 	uint8_t next = fetch_op();
28 	bool seg_prefix = false;
29 	int seg = 0;
30 
31 	switch (next)
32 	{
33 	case 0x26:
34 		seg_prefix = true;
35 		seg = ES;
36 		break;
37 	case 0x2e:
38 		seg_prefix = true;
39 		seg = CS;
40 		break;
41 	case 0x36:
42 		seg_prefix = true;
43 		seg = SS;
44 		break;
45 	case 0x3e:
46 		seg_prefix = true;
47 		seg = DS;
48 		break;
49 	}
50 
51 	if ( seg_prefix )
52 	{
53 		m_seg_prefix = true;
54 		m_seg_prefix_next = true;
55 		m_prefix_seg = seg;
56 		next = fetch_op();
57 		CLK(OVERRIDE);
58 	}
59 
60 	return next;
61 }
62 
63 
CLK(uint8_t op)64 inline void i8086_common_cpu_device::CLK(uint8_t op)
65 {
66 	m_icount -= m_timing[op];
67 }
68 
69 
CLKM(uint8_t op_reg,uint8_t op_mem)70 inline void i8086_common_cpu_device::CLKM(uint8_t op_reg, uint8_t op_mem)
71 {
72 	m_icount -= ( m_modrm >= 0xc0 ) ? m_timing[op_reg] : m_timing[op_mem];
73 }
74 
75 
get_ea(int size,int op)76 inline uint32_t i8086_common_cpu_device::get_ea(int size, int op)
77 {
78 	uint16_t e16;
79 
80 	switch( m_modrm & 0xc7 )
81 	{
82 	case 0x00:
83 		m_icount -= 7;
84 		m_eo = m_regs.w[BX] + m_regs.w[SI];
85 		m_ea = calc_addr(DS, m_eo, size, op);
86 		break;
87 	case 0x01:
88 		m_icount -= 8;
89 		m_eo = m_regs.w[BX] + m_regs.w[DI];
90 		m_ea = calc_addr(DS, m_eo, size, op);
91 		break;
92 	case 0x02:
93 		m_icount -= 8;
94 		m_eo = m_regs.w[BP] + m_regs.w[SI];
95 		m_ea = calc_addr(SS, m_eo, size, op);
96 		break;
97 	case 0x03:
98 		m_icount -= 7;
99 		m_eo = m_regs.w[BP] + m_regs.w[DI];
100 		m_ea = calc_addr(SS, m_eo, size, op);
101 		break;
102 	case 0x04:
103 		m_icount -= 5;
104 		m_eo = m_regs.w[SI];
105 		m_ea = calc_addr(DS, m_eo, size, op);
106 		break;
107 	case 0x05:
108 		m_icount -= 5;
109 		m_eo = m_regs.w[DI];
110 		m_ea = calc_addr(DS, m_eo, size, op);
111 		break;
112 	case 0x06:
113 		m_icount -= 6;
114 		m_eo = fetch_word();
115 		m_ea = calc_addr(DS, m_eo, size, op);
116 		break;
117 	case 0x07:
118 		m_icount -= 5;
119 		m_eo = m_regs.w[BX];
120 		m_ea = calc_addr(DS, m_eo, size, op);
121 		break;
122 
123 	case 0x40:
124 		m_icount -= 11;
125 		m_eo = m_regs.w[BX] + m_regs.w[SI] + (int8_t)fetch();
126 		m_ea = calc_addr(DS, m_eo, size, op);
127 		break;
128 	case 0x41:
129 		m_icount -= 12;
130 		m_eo = m_regs.w[BX] + m_regs.w[DI] + (int8_t)fetch();
131 		m_ea = calc_addr(DS, m_eo, size, op);
132 		break;
133 	case 0x42:
134 		m_icount -= 12;
135 		m_eo = m_regs.w[BP] + m_regs.w[SI] + (int8_t)fetch();
136 		m_ea = calc_addr(SS, m_eo, size, op);
137 		break;
138 	case 0x43:
139 		m_icount -= 11;
140 		m_eo = m_regs.w[BP] + m_regs.w[DI] + (int8_t)fetch();
141 		m_ea = calc_addr(SS, m_eo, size, op);
142 		break;
143 	case 0x44:
144 		m_icount -= 9;
145 		m_eo = m_regs.w[SI] + (int8_t)fetch();
146 		m_ea = calc_addr(DS, m_eo, size, op);
147 		break;
148 	case 0x45:
149 		m_icount -= 9;
150 		m_eo = m_regs.w[DI] + (int8_t)fetch();
151 		m_ea = calc_addr(DS, m_eo, size, op);
152 		break;
153 	case 0x46:
154 		m_icount -= 9;
155 		m_eo = m_regs.w[BP] + (int8_t)fetch();
156 		m_ea = calc_addr(SS, m_eo, size, op);
157 		break;
158 	case 0x47:
159 		m_icount -= 9;
160 		m_eo = m_regs.w[BX] + (int8_t)fetch();
161 		m_ea = calc_addr(DS, m_eo, size, op);
162 		break;
163 
164 	case 0x80:
165 		m_icount -= 11;
166 		e16 = fetch_word();
167 		m_eo = m_regs.w[BX] + m_regs.w[SI] + (int16_t)e16;
168 		m_ea = calc_addr(DS, m_eo, size, op);
169 		break;
170 	case 0x81:
171 		m_icount -= 12;
172 		e16 = fetch_word();
173 		m_eo = m_regs.w[BX] + m_regs.w[DI] + (int16_t)e16;
174 		m_ea = calc_addr(DS, m_eo, size, op);
175 		break;
176 	case 0x82:
177 		m_icount -= 11;
178 		e16 = fetch_word();
179 		m_eo = m_regs.w[BP] + m_regs.w[SI] + (int16_t)e16;
180 		m_ea = calc_addr(SS, m_eo, size, op);
181 		break;
182 	case 0x83:
183 		m_icount -= 11;
184 		e16 = fetch_word();
185 		m_eo = m_regs.w[BP] + m_regs.w[DI] + (int16_t)e16;
186 		m_ea = calc_addr(SS, m_eo, size, op);
187 		break;
188 	case 0x84:
189 		m_icount -= 9;
190 		e16 = fetch_word();
191 		m_eo = m_regs.w[SI] + (int16_t)e16;
192 		m_ea = calc_addr(DS, m_eo, size, op);
193 		break;
194 	case 0x85:
195 		m_icount -= 9;
196 		e16 = fetch_word();
197 		m_eo = m_regs.w[DI] + (int16_t)e16;
198 		m_ea = calc_addr(DS, m_eo, size, op);
199 		break;
200 	case 0x86:
201 		m_icount -= 9;
202 		e16 = fetch_word();
203 		m_eo = m_regs.w[BP] + (int16_t)e16;
204 		m_ea = calc_addr(SS, m_eo, size, op);
205 		break;
206 	case 0x87:
207 		m_icount -= 9;
208 		e16 = fetch_word();
209 		m_eo = m_regs.w[BX] + (int16_t)e16;
210 		m_ea = calc_addr(DS, m_eo, size, op);
211 		break;
212 	}
213 	return m_ea;
214 }
215 
216 
PutbackRMByte(uint8_t data)217 inline void i8086_common_cpu_device::PutbackRMByte(uint8_t data)
218 {
219 	if ( m_modrm >= 0xc0 )
220 	{
221 		m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = data;
222 	}
223 	else
224 	{
225 		write_byte(m_ea, data);
226 	}
227 }
228 
229 
PutbackRMWord(uint16_t data)230 inline void i8086_common_cpu_device::PutbackRMWord(uint16_t data)
231 {
232 	if ( m_modrm >= 0xc0 )
233 	{
234 		m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = data;
235 	}
236 	else
237 	{
238 		write_word(m_ea, data);
239 	}
240 }
241 
PutImmRMWord()242 inline void i8086_common_cpu_device::PutImmRMWord()
243 {
244 	if ( m_modrm >= 0xc0 )
245 	{
246 		m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = fetch_word();
247 	}
248 	else
249 	{
250 		uint32_t addr = get_ea(2, I8086_WRITE);
251 		write_word(addr, fetch_word());
252 	}
253 }
254 
PutRMWord(uint16_t val)255 inline void i8086_common_cpu_device::PutRMWord(uint16_t val)
256 {
257 	if ( m_modrm >= 0xc0 )
258 	{
259 		m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = val;
260 	}
261 	else
262 	{
263 		write_word(get_ea(2, I8086_WRITE), val);
264 	}
265 }
266 
267 
PutRMByte(uint8_t val)268 inline void i8086_common_cpu_device::PutRMByte(uint8_t val)
269 {
270 	if ( m_modrm >= 0xc0 )
271 	{
272 		m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = val;
273 	}
274 	else
275 	{
276 		write_byte(get_ea(1, I8086_WRITE), val);
277 	}
278 }
279 
280 
PutImmRMByte()281 inline void i8086_common_cpu_device::PutImmRMByte()
282 {
283 	if ( m_modrm >= 0xc0 )
284 	{
285 		m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = fetch();
286 	}
287 	else
288 	{
289 		uint32_t addr = get_ea(1, I8086_WRITE);
290 		write_byte(addr, fetch());
291 	}
292 }
293 
294 
DEF_br8()295 inline void i8086_common_cpu_device::DEF_br8()
296 {
297 	m_modrm = fetch();
298 	m_src = RegByte();
299 	m_dst = GetRMByte();
300 }
301 
302 
DEF_wr16()303 inline void i8086_common_cpu_device::DEF_wr16()
304 {
305 	m_modrm = fetch();
306 	m_src = RegWord();
307 	m_dst = GetRMWord();
308 }
309 
310 
DEF_r8b()311 inline void i8086_common_cpu_device::DEF_r8b()
312 {
313 	m_modrm = fetch();
314 	m_dst = RegByte();
315 	m_src = GetRMByte();
316 }
317 
318 
DEF_r16w()319 inline void i8086_common_cpu_device::DEF_r16w()
320 {
321 	m_modrm = fetch();
322 	m_dst = RegWord();
323 	m_src = GetRMWord();
324 }
325 
326 
DEF_ald8()327 inline void i8086_common_cpu_device::DEF_ald8()
328 {
329 	m_src = fetch();
330 	m_dst = m_regs.b[AL];
331 }
332 
333 
DEF_axd16()334 inline void i8086_common_cpu_device::DEF_axd16()
335 {
336 	m_src = fetch_word();
337 	m_dst = m_regs.w[AX];
338 }
339 
340 
341 
RegByte(uint8_t data)342 inline void i8086_common_cpu_device::RegByte(uint8_t data)
343 {
344 	m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ] = data;
345 }
346 
347 
RegWord(uint16_t data)348 inline void i8086_common_cpu_device::RegWord(uint16_t data)
349 {
350 	m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ] = data;
351 }
352 
353 
RegByte()354 inline uint8_t i8086_common_cpu_device::RegByte()
355 {
356 	return m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ];
357 }
358 
359 
RegWord()360 inline uint16_t i8086_common_cpu_device::RegWord()
361 {
362 	return m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ];
363 }
364 
365 
GetRMWord()366 inline uint16_t i8086_common_cpu_device::GetRMWord()
367 {
368 	if ( m_modrm >= 0xc0 )
369 	{
370 		return m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ];
371 	}
372 	else
373 	{
374 		return read_word(get_ea(2, I8086_READ));
375 	}
376 }
377 
378 
GetnextRMWord()379 inline uint16_t i8086_common_cpu_device::GetnextRMWord()
380 {
381 	return read_word((m_ea & ~0xffff) | ((m_ea + 2) & 0xffff));
382 }
383 
384 
GetRMByte()385 inline uint8_t i8086_common_cpu_device::GetRMByte()
386 {
387 	if ( m_modrm >= 0xc0 )
388 	{
389 		return m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ];
390 	}
391 	else
392 	{
393 		return read_byte(get_ea(1, I8086_READ));
394 	}
395 }
396 
397 
PutMemB(int seg,uint16_t offset,uint8_t data)398 inline void i8086_common_cpu_device::PutMemB(int seg, uint16_t offset, uint8_t data)
399 {
400 	write_byte(calc_addr(seg, offset, 1, I8086_WRITE), data);
401 }
402 
403 
PutMemW(int seg,uint16_t offset,uint16_t data)404 inline void i8086_common_cpu_device::PutMemW(int seg, uint16_t offset, uint16_t data)
405 {
406 	write_word(calc_addr(seg, offset, 2, I8086_WRITE), data);
407 }
408 
409 
GetMemB(int seg,uint16_t offset)410 inline uint8_t i8086_common_cpu_device::GetMemB(int seg, uint16_t offset)
411 {
412 	return read_byte(calc_addr(seg, offset, 1, I8086_READ));
413 }
414 
415 
GetMemW(int seg,uint16_t offset)416 inline uint16_t i8086_common_cpu_device::GetMemW(int seg, uint16_t offset)
417 {
418 	return read_word(calc_addr(seg, offset, 2, I8086_READ));
419 }
420 
421 
422 // Setting flags
423 
set_CFB(uint32_t x)424 inline void i8086_common_cpu_device::set_CFB(uint32_t x)
425 {
426 	m_CarryVal = x & 0x100;
427 }
428 
set_CFW(uint32_t x)429 inline void i8086_common_cpu_device::set_CFW(uint32_t x)
430 {
431 	m_CarryVal = x & 0x10000;
432 }
433 
set_AF(uint32_t x,uint32_t y,uint32_t z)434 inline void i8086_common_cpu_device::set_AF(uint32_t x,uint32_t y,uint32_t z)
435 {
436 	m_AuxVal = (x ^ (y ^ z)) & 0x10;
437 }
438 
set_SF(uint32_t x)439 inline void i8086_common_cpu_device::set_SF(uint32_t x)
440 {
441 	m_SignVal = x;
442 }
443 
set_ZF(uint32_t x)444 inline void i8086_common_cpu_device::set_ZF(uint32_t x)
445 {
446 	m_ZeroVal = x;
447 }
448 
set_PF(uint32_t x)449 inline void i8086_common_cpu_device::set_PF(uint32_t x)
450 {
451 	m_ParityVal = x;
452 }
453 
set_SZPF_Byte(uint32_t x)454 inline void i8086_common_cpu_device::set_SZPF_Byte(uint32_t x)
455 {
456 	m_SignVal = m_ZeroVal = m_ParityVal = (int8_t)x;
457 }
458 
set_SZPF_Word(uint32_t x)459 inline void i8086_common_cpu_device::set_SZPF_Word(uint32_t x)
460 {
461 	m_SignVal = m_ZeroVal = m_ParityVal = (int16_t)x;
462 }
463 
set_OFW_Add(uint32_t x,uint32_t y,uint32_t z)464 inline void i8086_common_cpu_device::set_OFW_Add(uint32_t x,uint32_t y,uint32_t z)
465 {
466 	m_OverVal = (x ^ y) & (x ^ z) & 0x8000;
467 }
468 
set_OFB_Add(uint32_t x,uint32_t y,uint32_t z)469 inline void i8086_common_cpu_device::set_OFB_Add(uint32_t x,uint32_t y,uint32_t z)
470 {
471 	m_OverVal = (x ^ y) & (x ^ z) & 0x80;
472 }
473 
set_OFW_Sub(uint32_t x,uint32_t y,uint32_t z)474 inline void i8086_common_cpu_device::set_OFW_Sub(uint32_t x,uint32_t y,uint32_t z)
475 {
476 	m_OverVal = (z ^ y) & (z ^ x) & 0x8000;
477 }
478 
set_OFB_Sub(uint32_t x,uint32_t y,uint32_t z)479 inline void i8086_common_cpu_device::set_OFB_Sub(uint32_t x,uint32_t y,uint32_t z)
480 {
481 	m_OverVal = (z ^ y) & (z ^ x) & 0x80;
482 }
483 
484 
CompressFlags()485 inline uint16_t i8086_common_cpu_device::CompressFlags() const
486 {
487 	return (CF ? 1 : 0)
488 		| (1 << 1)
489 		| (PF ? 4 : 0)
490 		| (AF ? 0x10 : 0)
491 		| (ZF ? 0x40 : 0)
492 		| (SF ? 0x80 : 0)
493 		| (m_TF << 8)
494 		| (m_IF << 9)
495 		| (m_DF << 10)
496 		| (OF << 11)
497 		| (m_IOPL << 12)
498 		| (m_NT << 14)
499 		| (m_MF << 15);
500 }
501 
ExpandFlags(uint16_t f)502 inline void i8086_common_cpu_device::ExpandFlags(uint16_t f)
503 {
504 	m_CarryVal = (f) & 1;
505 	m_ParityVal = !((f) & 4);
506 	m_AuxVal = (f) & 16;
507 	m_ZeroVal = !((f) & 64);
508 	m_SignVal = (f) & 128 ? -1 : 0;
509 	m_TF = ((f) & 256) == 256;
510 	m_IF = ((f) & 512) == 512;
511 	m_DF = ((f) & 1024) == 1024;
512 	m_OverVal = (f) & 2048;
513 	m_IOPL = (f >> 12) & 3;
514 	m_NT = ((f) & 0x4000) == 0x4000;
515 	m_MF = ((f) & 0x8000) == 0x8000;
516 }
517 
i_insb()518 inline void i8086_common_cpu_device::i_insb()
519 {
520 	uint32_t ea = calc_addr(ES, m_regs.w[DI], 1, I8086_WRITE);
521 	write_byte(ea, read_port_byte(m_regs.w[DX]));
522 	m_regs.w[DI] += -2 * m_DF + 1;
523 	CLK(IN_IMM8);
524 }
525 
i_insw()526 inline void i8086_common_cpu_device::i_insw()
527 {
528 	uint32_t ea = calc_addr(ES, m_regs.w[DI], 2, I8086_WRITE);
529 	write_word(ea, read_port_word(m_regs.w[DX]));
530 	m_regs.w[DI] += -4 * m_DF + 2;
531 	CLK(IN_IMM16);
532 }
533 
i_outsb()534 inline void i8086_common_cpu_device::i_outsb()
535 {
536 	write_port_byte(m_regs.w[DX], GetMemB(DS, m_regs.w[SI]));
537 	m_regs.w[SI] += -2 * m_DF + 1;
538 	CLK(OUT_IMM8);
539 }
540 
i_outsw()541 inline void i8086_common_cpu_device::i_outsw()
542 {
543 	write_port_word(m_regs.w[DX], GetMemW(DS, m_regs.w[SI]));
544 	m_regs.w[SI] += -4 * m_DF + 2;
545 	CLK(OUT_IMM16);
546 }
547 
i_movsb()548 inline void i8086_common_cpu_device::i_movsb()
549 {
550 	uint8_t tmp = GetMemB( DS, m_regs.w[SI] );
551 	PutMemB( ES, m_regs.w[DI], tmp);
552 	m_regs.w[DI] += -2 * m_DF + 1;
553 	m_regs.w[SI] += -2 * m_DF + 1;
554 	CLK(MOVS8);
555 }
556 
i_movsw()557 inline void i8086_common_cpu_device::i_movsw()
558 {
559 	uint16_t tmp = GetMemW( DS, m_regs.w[SI] );
560 	PutMemW( ES, m_regs.w[DI], tmp );
561 	m_regs.w[DI] += -4 * m_DF + 2;
562 	m_regs.w[SI] += -4 * m_DF + 2;
563 	CLK(MOVS16);
564 }
565 
i_cmpsb()566 inline void i8086_common_cpu_device::i_cmpsb()
567 {
568 	m_src = GetMemB( ES, m_regs.w[DI] );
569 	m_dst = GetMemB( DS, m_regs.w[SI] );
570 	set_CFB(SUBB());
571 	m_regs.w[DI] += -2 * m_DF + 1;
572 	m_regs.w[SI] += -2 * m_DF + 1;
573 	CLK(CMPS8);
574 }
575 
i_cmpsw()576 inline void i8086_common_cpu_device::i_cmpsw()
577 {
578 	m_src = GetMemW( ES, m_regs.w[DI] );
579 	m_dst = GetMemW( DS, m_regs.w[SI] );
580 	set_CFW(SUBX());
581 	m_regs.w[DI] += -4 * m_DF + 2;
582 	m_regs.w[SI] += -4 * m_DF + 2;
583 	CLK(CMPS16);
584 }
585 
i_stosb()586 inline void i8086_common_cpu_device::i_stosb()
587 {
588 	PutMemB( ES, m_regs.w[DI], m_regs.b[AL] );
589 	m_regs.w[DI] += -2 * m_DF + 1;
590 	CLK(STOS8);
591 }
592 
i_stosw()593 inline void i8086_common_cpu_device::i_stosw()
594 {
595 	PutMemW( ES, m_regs.w[DI], m_regs.w[AX] );
596 	m_regs.w[DI] += -4 * m_DF + 2;
597 	CLK(STOS16);
598 }
599 
i_lodsb()600 inline void i8086_common_cpu_device::i_lodsb()
601 {
602 	m_regs.b[AL] = GetMemB( DS, m_regs.w[SI] );
603 	m_regs.w[SI] += -2 * m_DF + 1;
604 	CLK(LODS8);
605 }
606 
i_lodsw()607 inline void i8086_common_cpu_device::i_lodsw()
608 {
609 	m_regs.w[AX] = GetMemW( DS, m_regs.w[SI] );
610 	m_regs.w[SI] += -4 * m_DF + 2;
611 	CLK(LODS16);
612 }
613 
i_scasb()614 inline void i8086_common_cpu_device::i_scasb()
615 {
616 	m_src = GetMemB( ES, m_regs.w[DI] );
617 	m_dst = m_regs.b[AL];
618 	set_CFB(SUBB());
619 	m_regs.w[DI] += -2 * m_DF + 1;
620 	CLK(SCAS8);
621 }
622 
i_scasw()623 inline void i8086_common_cpu_device::i_scasw()
624 {
625 	m_src = GetMemW( ES, m_regs.w[DI] );
626 	m_dst = m_regs.w[AX];
627 	set_CFW(SUBX());
628 	m_regs.w[DI] += -4 * m_DF + 2;
629 	CLK(SCAS16);
630 }
631 
632 
i_popf()633 inline void i8086_common_cpu_device::i_popf()
634 {
635 	uint32_t tmp = POP();
636 
637 	ExpandFlags(tmp | 0xf000);
638 	CLK(POPF);
639 	if (m_TF)
640 	{
641 		m_fire_trap = 1;
642 	}
643 }
644 
645 
ADDB()646 inline uint32_t i8086_common_cpu_device::ADDB()
647 {
648 	uint32_t res = m_dst + m_src;
649 
650 	set_OFB_Add(res,m_src,m_dst);
651 	set_AF(res,m_src,m_dst);
652 	set_SZPF_Byte(res);
653 	m_dst = res & 0xff;
654 	return res;
655 }
656 
657 
ADDX()658 inline uint32_t i8086_common_cpu_device::ADDX()
659 {
660 	uint32_t res = m_dst + m_src;
661 
662 	set_OFW_Add(res,m_src,m_dst);
663 	set_AF(res,m_src,m_dst);
664 	set_SZPF_Word(res);
665 	m_dst = res & 0xffff;
666 	return res;
667 }
668 
669 
SUBB()670 inline uint32_t i8086_common_cpu_device::SUBB()
671 {
672 	uint32_t res = m_dst - m_src;
673 
674 	set_OFB_Sub(res,m_src,m_dst);
675 	set_AF(res,m_src,m_dst);
676 	set_SZPF_Byte(res);
677 	m_dst = res & 0xff;
678 	return res;
679 }
680 
681 
SUBX()682 inline uint32_t i8086_common_cpu_device::SUBX()
683 {
684 	uint32_t res = m_dst - m_src;
685 
686 	set_OFW_Sub(res,m_src,m_dst);
687 	set_AF(res,m_src,m_dst);
688 	set_SZPF_Word(res);
689 	m_dst = res & 0xffff;
690 	return res;
691 }
692 
693 
ORB()694 inline void i8086_common_cpu_device::ORB()
695 {
696 	m_dst |= m_src;
697 	m_CarryVal = m_OverVal = m_AuxVal = 0;
698 	set_SZPF_Byte(m_dst);
699 }
700 
701 
ORW()702 inline void i8086_common_cpu_device::ORW()
703 {
704 	m_dst |= m_src;
705 	m_CarryVal = m_OverVal = m_AuxVal = 0;
706 	set_SZPF_Word(m_dst);
707 }
708 
709 
ANDB()710 inline void i8086_common_cpu_device::ANDB()
711 {
712 	m_dst &= m_src;
713 	m_CarryVal = m_OverVal = m_AuxVal = 0;
714 	set_SZPF_Byte(m_dst);
715 }
716 
717 
ANDX()718 inline void i8086_common_cpu_device::ANDX()
719 {
720 	m_dst &= m_src;
721 	m_CarryVal = m_OverVal = m_AuxVal = 0;
722 	set_SZPF_Word(m_dst);
723 }
724 
725 
XORB()726 inline void i8086_common_cpu_device::XORB()
727 {
728 	m_dst ^= m_src;
729 	m_CarryVal = m_OverVal = m_AuxVal = 0;
730 	set_SZPF_Byte(m_dst);
731 }
732 
733 
XORW()734 inline void i8086_common_cpu_device::XORW()
735 {
736 	m_dst ^= m_src;
737 	m_CarryVal = m_OverVal = m_AuxVal = 0;
738 	set_SZPF_Word(m_dst);
739 }
740 
741 
ROL_BYTE()742 inline void i8086_common_cpu_device::ROL_BYTE()
743 {
744 	m_CarryVal = m_dst & 0x80;
745 	m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
746 }
747 
ROL_WORD()748 inline void i8086_common_cpu_device::ROL_WORD()
749 {
750 	m_CarryVal = m_dst & 0x8000;
751 	m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
752 }
753 
ROR_BYTE()754 inline void i8086_common_cpu_device::ROR_BYTE()
755 {
756 	m_CarryVal = m_dst & 0x1;
757 	m_dst = (m_dst >> 1) | (CF ? 0x80 : 0x00);
758 }
759 
ROR_WORD()760 inline void i8086_common_cpu_device::ROR_WORD()
761 {
762 	m_CarryVal = m_dst & 0x1;
763 	m_dst = (m_dst >> 1) + (CF ? 0x8000 : 0x0000);
764 }
765 
ROLC_BYTE()766 inline void i8086_common_cpu_device::ROLC_BYTE()
767 {
768 	m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
769 	set_CFB(m_dst);
770 }
771 
ROLC_WORD()772 inline void i8086_common_cpu_device::ROLC_WORD()
773 {
774 	m_dst = (m_dst << 1) | ( CF ? 1 : 0 );
775 	set_CFW(m_dst);
776 }
777 
RORC_BYTE()778 inline void i8086_common_cpu_device::RORC_BYTE()
779 {
780 	m_dst |= ( CF ? 0x100 : 0x00);
781 	m_CarryVal = m_dst & 0x01;
782 	m_dst >>= 1;
783 }
784 
RORC_WORD()785 inline void i8086_common_cpu_device::RORC_WORD()
786 {
787 	m_dst |= ( CF ? 0x10000 : 0);
788 	m_CarryVal = m_dst & 0x01;
789 	m_dst >>= 1;
790 }
791 
SHL_BYTE(uint8_t c)792 inline void i8086_common_cpu_device::SHL_BYTE(uint8_t c)
793 {
794 	while (c--)
795 		m_dst <<= 1;
796 
797 	set_CFB(m_dst);
798 	set_SZPF_Byte(m_dst);
799 	PutbackRMByte(m_dst);
800 }
801 
SHL_WORD(uint8_t c)802 inline void i8086_common_cpu_device::SHL_WORD(uint8_t c)
803 {
804 	while (c--)
805 		m_dst <<= 1;
806 
807 	set_CFW(m_dst);
808 	set_SZPF_Word(m_dst);
809 	PutbackRMWord(m_dst);
810 }
811 
SHR_BYTE(uint8_t c)812 inline void i8086_common_cpu_device::SHR_BYTE(uint8_t c)
813 {
814 	while (c--)
815 	{
816 		m_CarryVal = m_dst & 0x01;
817 		m_dst >>= 1;
818 	}
819 
820 	set_SZPF_Byte(m_dst);
821 	PutbackRMByte(m_dst);
822 }
823 
SHR_WORD(uint8_t c)824 inline void i8086_common_cpu_device::SHR_WORD(uint8_t c)
825 {
826 	while (c--)
827 	{
828 		m_CarryVal = m_dst & 0x01;
829 		m_dst >>= 1;
830 	}
831 
832 	set_SZPF_Word(m_dst);
833 	PutbackRMWord(m_dst);
834 }
835 
SHRA_BYTE(uint8_t c)836 inline void i8086_common_cpu_device::SHRA_BYTE(uint8_t c)
837 {
838 	while (c--)
839 	{
840 		m_CarryVal = m_dst & 0x01;
841 		m_dst = ((int8_t) m_dst) >> 1;
842 	}
843 
844 	set_SZPF_Byte(m_dst);
845 	PutbackRMByte(m_dst);
846 }
847 
SHRA_WORD(uint8_t c)848 inline void i8086_common_cpu_device::SHRA_WORD(uint8_t c)
849 {
850 	while (c--)
851 	{
852 		m_CarryVal = m_dst & 0x01;
853 		m_dst = ((int16_t) m_dst) >> 1;
854 	}
855 
856 	set_SZPF_Word(m_dst);
857 	PutbackRMWord(m_dst);
858 }
859 
860 
XchgAXReg(uint8_t reg)861 inline void i8086_common_cpu_device::XchgAXReg(uint8_t reg)
862 {
863 	uint16_t tmp = m_regs.w[reg];
864 
865 	m_regs.w[reg] = m_regs.w[AX];
866 	m_regs.w[AX] = tmp;
867 }
868 
869 
IncWordReg(uint8_t reg)870 inline void i8086_common_cpu_device::IncWordReg(uint8_t reg)
871 {
872 	uint32_t tmp = m_regs.w[reg];
873 	uint32_t tmp1 = tmp+1;
874 
875 	m_OverVal = (tmp == 0x7fff);
876 	set_AF(tmp1,tmp,1);
877 	set_SZPF_Word(tmp1);
878 	m_regs.w[reg] = tmp1;
879 }
880 
881 
DecWordReg(uint8_t reg)882 inline void i8086_common_cpu_device::DecWordReg(uint8_t reg)
883 {
884 	uint32_t tmp = m_regs.w[reg];
885 	uint32_t tmp1 = tmp-1;
886 
887 	m_OverVal = (tmp == 0x8000);
888 	set_AF(tmp1,tmp,1);
889 	set_SZPF_Word(tmp1);
890 	m_regs.w[reg] = tmp1;
891 }
892 
893 
PUSH(uint16_t data)894 inline void i8086_common_cpu_device::PUSH(uint16_t data)
895 {
896 	write_word(calc_addr(SS, m_regs.w[SP] - 2, 2, I8086_WRITE, false), data);
897 	m_regs.w[SP] -= 2;
898 }
899 
900 
POP()901 inline uint16_t i8086_common_cpu_device::POP()
902 {
903 	uint16_t data = read_word(calc_addr(SS, m_regs.w[SP], 2, I8086_READ, false));
904 
905 	m_regs.w[SP] += 2;
906 	return data;
907 }
908 
909 
JMP(bool cond)910 inline void i8086_common_cpu_device::JMP(bool cond)
911 {
912 	int rel  = (int)((int8_t)fetch());
913 
914 	if (cond)
915 	{
916 		m_ip += rel;
917 		CLK(JCC_T);
918 	}
919 	else
920 		CLK(JCC_NT);
921 }
922 
923 
ADJ4(int8_t param1,int8_t param2)924 inline void i8086_common_cpu_device::ADJ4(int8_t param1,int8_t param2)
925 {
926 	if (AF || ((m_regs.b[AL] & 0xf) > 9))
927 	{
928 		uint16_t tmp;
929 		tmp = m_regs.b[AL] + param1;
930 		m_regs.b[AL] = tmp;
931 		m_AuxVal = 1;
932 		m_CarryVal |= tmp & 0x100;
933 	}
934 	if (CF || (m_regs.b[AL]>0x9f))
935 	{
936 		m_regs.b[AL] += param2;
937 		m_CarryVal = 1;
938 	}
939 	set_SZPF_Byte(m_regs.b[AL]);
940 }
941 
942 
ADJB(int8_t param1,int8_t param2)943 inline void i8086_common_cpu_device::ADJB(int8_t param1, int8_t param2)
944 {
945 	if (AF || ((m_regs.b[AL] & 0xf) > 9))
946 	{
947 		m_regs.b[AL] += param1;
948 		m_regs.b[AH] += param2;
949 		m_AuxVal = 1;
950 		m_CarryVal = 1;
951 	}
952 	else
953 	{
954 		m_AuxVal = 0;
955 		m_CarryVal = 0;
956 	}
957 	m_regs.b[AL] &= 0x0F;
958 }
959