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