1 /***************************************************************
2 * Enter HALT state; write 1 to fake port on first execution
3 ***************************************************************/
4 #define ENTER_HALT { \
5 _PC--; \
6 _HALT = 1; \
7 if( !after_EI ) \
8 z180_burn( z180_icount ); \
9 }
10
11 /***************************************************************
12 * Leave HALT state; write 0 to fake port
13 ***************************************************************/
14 #define LEAVE_HALT { \
15 if( _HALT ) \
16 { \
17 _HALT = 0; \
18 _PC++; \
19 } \
20 }
21
22 /***************************************************************
23 * Input a byte from given I/O port
24 ***************************************************************/
25 #define IN(port) \
26 (((port ^ IO_IOCR) & 0xffc0) == 0) ? \
27 z180_readcontrol(port) : cpu_readport16(port)
28
29 /***************************************************************
30 * Output a byte to given I/O port
31 ***************************************************************/
32 #define OUT(port,value) \
33 if (((port ^ IO_IOCR) & 0xffc0) == 0) \
34 z180_writecontrol(port,value); \
35 else cpu_writeport16(port,value)
36
37 /***************************************************************
38 * MMU calculate the memory managemant lookup table
39 * bb and cb specify a 4K page
40 * If the 4 most significant bits of an 16 bit address are
41 * greater or equal to the bank base, the bank base register
42 * specifies the 4K offset into the 20 bit address space.
43 * If the 4 bits are also greater or equal to the common base,
44 * the common base register is used to specify the offset.
45 ***************************************************************/
z180_mmu(void)46 static INLINE void z180_mmu( void )
47 {
48 offs_t addr, page, bb, cb;
49 bb = IO_CBAR & 15;
50 cb = IO_CBAR >> 4;
51 for( page = 0; page < 16; page++ )
52 {
53 addr = page << 12;
54 if (page >= bb)
55 {
56 if (page >= cb)
57 addr += IO_CBR << 12;
58 else
59 addr += IO_BBR << 12;
60 }
61 Z180.mmu[page] = addr;
62 }
63 }
64
65
66 #define MMU_REMAP_ADDR(addr) (Z180.mmu[((addr)>>12)&15]|((addr)&4095))
67
68 /***************************************************************
69 * Read a byte from given memory location
70 ***************************************************************/
71 #define RM(addr) cpu_readmem20(MMU_REMAP_ADDR(addr))
cpu_readmemz180(offs_t offset)72 data8_t cpu_readmemz180(offs_t offset)
73 {
74 return RM(offset);
75 }
76
77 /***************************************************************
78 * Write a byte to given memory location
79 ***************************************************************/
80 #define WM(addr,value) cpu_writemem20(MMU_REMAP_ADDR(addr),value)
cpu_writememz180(offs_t offset,data8_t data)81 void cpu_writememz180(offs_t offset, data8_t data)
82 {
83 WM(offset, data);
84 }
85
86 /***************************************************************
87 * Read a word from given memory location
88 ***************************************************************/
RM16(offs_t addr,PAIR * r)89 static INLINE void RM16( offs_t addr, PAIR *r )
90 {
91 r->b.l = RM(addr);
92 r->b.h = RM(addr+1);
93 }
94
95 /***************************************************************
96 * Write a word to given memory location
97 ***************************************************************/
WM16(offs_t addr,PAIR * r)98 static INLINE void WM16( offs_t addr, PAIR *r )
99 {
100 WM(addr,r->b.l);
101 WM(addr+1,r->b.h);
102 }
103
104 /***************************************************************
105 * ROP() is identical to RM() except it is used for
106 * reading opcodes. In case of system with memory mapped I/O,
107 * this function can be used to greatly speed up emulation
108 ***************************************************************/
ROP(void)109 static INLINE UINT8 ROP(void)
110 {
111 offs_t addr = _PCD;
112 _PC++;
113 return cpu_readop(MMU_REMAP_ADDR(addr));
114 }
115
116 /****************************************************************
117 * ARG() is identical to ROP() except it is used
118 * for reading opcode arguments. This difference can be used to
119 * support systems that use different encoding mechanisms for
120 * opcodes and opcode arguments
121 ***************************************************************/
ARG(void)122 static INLINE UINT8 ARG(void)
123 {
124 offs_t addr = _PCD;
125 _PC++;
126 return cpu_readop_arg(MMU_REMAP_ADDR(addr));
127 }
128
ARG16(void)129 static INLINE UINT32 ARG16(void)
130 {
131 offs_t addr = _PCD;
132 _PC += 2;
133 return cpu_readop_arg(MMU_REMAP_ADDR(addr)) | (cpu_readop_arg(MMU_REMAP_ADDR(addr+1)) << 8);
134 }
135
136 /****************************************************************************
137 * Change program counter - MMU lookup
138 ****************************************************************************/
139 #define z180_change_pc(addr) change_pc20(MMU_REMAP_ADDR(addr))
cpu_setOPbasez180(int pc)140 void cpu_setOPbasez180(int pc)
141 {
142 z180_change_pc(pc);
143 }
144
145 /***************************************************************
146 * Calculate the effective addess EA of an opcode using
147 * IX+offset resp. IY+offset addressing.
148 ***************************************************************/
149 #define EAX EA = (UINT32)(UINT16)(_IX+(INT8)ARG())
150 #define EAY EA = (UINT32)(UINT16)(_IY+(INT8)ARG())
151
152 /***************************************************************
153 * POP
154 ***************************************************************/
155 #define POP(DR) { RM16( _SPD, &Z180.DR ); _SP += 2; }
156
157 /***************************************************************
158 * PUSH
159 ***************************************************************/
160 #define PUSH(SR) { _SP -= 2; WM16( _SPD, &Z180.SR ); }
161
162 /***************************************************************
163 * JP
164 ***************************************************************/
165 #if BUSY_LOOP_HACKS
166 #define JP { \
167 unsigned oldpc = _PCD-1; \
168 _PCD = ARG16(); \
169 z180_change_pc(_PCD); \
170 /* speed up busy loop */ \
171 if( _PCD == oldpc ) \
172 { \
173 if( !after_EI ) \
174 BURNODD( z180_icount, 1, cc[Z180_TABLE_op][0xc3] ); \
175 } \
176 else \
177 { \
178 UINT8 op = cpu_readop(_PCD); \
179 if( _PCD == oldpc-1 ) \
180 { \
181 /* NOP - JP $-1 or EI - JP $-1 */ \
182 if ( op == 0x00 || op == 0xfb ) \
183 { \
184 if( !after_EI ) \
185 BURNODD( z180_icount-cc[Z180_TABLE_op][0x00],\
186 2, cc[Z180_TABLE_op][0x00]+cc[Z180_TABLE_op][0xc3]); \
187 } \
188 } \
189 else \
190 /* LD SP,#xxxx - JP $-3 (Galaga) */ \
191 if( _PCD == oldpc-3 && op == 0x31 ) \
192 { \
193 if( !after_EI ) \
194 BURNODD( z180_icount-cc[Z180_TABLE_op][0x31], \
195 2, cc[Z180_TABLE_op][0x31]+cc[Z180_TABLE_op][0xc3]); \
196 } \
197 } \
198 }
199 #else
200 #define JP { \
201 _PCD = ARG16(); \
202 z180_change_pc(_PCD); \
203 }
204 #endif
205
206 /***************************************************************
207 * JP_COND
208 ***************************************************************/
209
210 #define JP_COND(cond) \
211 if( cond ) \
212 { \
213 _PCD = ARG16(); \
214 z180_change_pc(_PCD); \
215 } \
216 else \
217 { \
218 _PC += 2; \
219 }
220
221 /***************************************************************
222 * JR
223 ***************************************************************/
224 #define JR() \
225 { \
226 unsigned oldpc = _PCD-1; \
227 INT8 arg = (INT8)ARG(); /* ARG() also increments _PC */ \
228 _PC += arg; /* so don't do _PC += ARG() */ \
229 z180_change_pc(_PCD); \
230 /* speed up busy loop */ \
231 if( _PCD == oldpc ) \
232 { \
233 if( !after_EI ) \
234 BURNODD( z180_icount, 1, cc[Z180_TABLE_op][0x18] ); \
235 } \
236 else \
237 { \
238 UINT8 op = cpu_readop(_PCD); \
239 if( _PCD == oldpc-1 ) \
240 { \
241 /* NOP - JR $-1 or EI - JR $-1 */ \
242 if ( op == 0x00 || op == 0xfb ) \
243 { \
244 if( !after_EI ) \
245 BURNODD( z180_icount-cc[Z180_TABLE_op][0x00],\
246 2, cc[Z180_TABLE_op][0x00]+cc[Z180_TABLE_op][0x18]); \
247 } \
248 } \
249 else \
250 /* LD SP,#xxxx - JR $-3 */ \
251 if( _PCD == oldpc-3 && op == 0x31 ) \
252 { \
253 if( !after_EI ) \
254 BURNODD( z180_icount-cc[Z180_TABLE_op][0x31], \
255 2, cc[Z180_TABLE_op][0x31]+cc[Z180_TABLE_op][0x18]); \
256 } \
257 } \
258 }
259
260 /***************************************************************
261 * JR_COND
262 ***************************************************************/
263 #define JR_COND(cond,opcode) \
264 if( cond ) \
265 { \
266 INT8 arg = (INT8)ARG(); /* ARG() also increments _PC */ \
267 _PC += arg; /* so don't do _PC += ARG() */ \
268 CC(ex,opcode); \
269 z180_change_pc(_PCD); \
270 } \
271 else _PC++; \
272
273 /***************************************************************
274 * CALL
275 ***************************************************************/
276 #define CALL() \
277 EA = ARG16(); \
278 PUSH( PC ); \
279 _PCD = EA; \
280 z180_change_pc(_PCD)
281
282 /***************************************************************
283 * CALL_COND
284 ***************************************************************/
285 #define CALL_COND(cond,opcode) \
286 if( cond ) \
287 { \
288 EA = ARG16(); \
289 PUSH( PC ); \
290 _PCD = EA; \
291 CC(ex,opcode); \
292 z180_change_pc(_PCD); \
293 } \
294 else \
295 { \
296 _PC+=2; \
297 }
298
299 /***************************************************************
300 * RET_COND
301 ***************************************************************/
302 #define RET_COND(cond,opcode) \
303 if( cond ) \
304 { \
305 POP(PC); \
306 z180_change_pc(_PCD); \
307 CC(ex,opcode); \
308 }
309
310 /***************************************************************
311 * RETN
312 ***************************************************************/
313 #define RETN { \
314 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d RETN IFF1:%d IFF2:%d\n", cpu_getactivecpu(), _IFF1, _IFF2); \
315 POP(PC); \
316 z180_change_pc(_PCD); \
317 if( _IFF1 == 0 && _IFF2 == 1 ) \
318 { \
319 _IFF1 = 1; \
320 if( Z180.irq_state[0] != CLEAR_LINE || \
321 Z180.request_irq >= 0 ) \
322 { \
323 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d RETN takes INT0\n", \
324 cpu_getactivecpu()); \
325 take_interrupt(Z180_INT0); \
326 } \
327 else if( Z180.irq_state[1] != CLEAR_LINE ) \
328 { \
329 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d RETN takes INT1\n", \
330 cpu_getactivecpu()); \
331 take_interrupt(Z180_INT1); \
332 } \
333 else if( Z180.irq_state[2] != CLEAR_LINE ) \
334 { \
335 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d RETN takes INT2\n", \
336 cpu_getactivecpu()); \
337 take_interrupt(Z180_INT2); \
338 } \
339 } \
340 else _IFF1 = _IFF2; \
341 }
342
343 /***************************************************************
344 * RETI
345 ***************************************************************/
346 #define RETI { \
347 int device = Z180.service_irq; \
348 POP(PC); \
349 z180_change_pc(_PCD); \
350 /* according to http://www.msxnet.org/tech/Z80/z80undoc.txt */ \
351 /* _IFF1 = _IFF2; */ \
352 if( device >= 0 ) \
353 { \
354 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d RETI device %d: $%02x\n", \
355 cpu_getactivecpu(), device, Z180.irq[device].irq_param); \
356 Z180.irq[device].interrupt_reti(Z180.irq[device].irq_param); \
357 } \
358 }
359
360 /***************************************************************
361 * LD R,A
362 ***************************************************************/
363 #define LD_R_A { \
364 _R = _A; \
365 _R2 = _A & 0x80; /* keep bit 7 of R */ \
366 }
367
368 /***************************************************************
369 * LD A,R
370 ***************************************************************/
371 #define LD_A_R { \
372 _A = (_R & 0x7f) | _R2; \
373 _F = (_F & CF) | SZ[_A] | ( _IFF2 << 2 ); \
374 }
375
376 /***************************************************************
377 * LD I,A
378 ***************************************************************/
379 #define LD_I_A { \
380 _I = _A; \
381 }
382
383 /***************************************************************
384 * LD A,I
385 ***************************************************************/
386 #define LD_A_I { \
387 _A = _I; \
388 _F = (_F & CF) | SZ[_A] | ( _IFF2 << 2 ); \
389 }
390
391 /***************************************************************
392 * RST
393 ***************************************************************/
394 #define RST(addr) \
395 PUSH( PC ); \
396 _PCD = addr; \
397 z180_change_pc(_PCD)
398
399 /***************************************************************
400 * INC r8
401 ***************************************************************/
INC(UINT8 value)402 static INLINE UINT8 INC(UINT8 value)
403 {
404 UINT8 res = value + 1;
405 _F = (_F & CF) | SZHV_inc[res];
406 return (UINT8)res;
407 }
408
409 /***************************************************************
410 * DEC r8
411 ***************************************************************/
DEC(UINT8 value)412 static INLINE UINT8 DEC(UINT8 value)
413 {
414 UINT8 res = value - 1;
415 _F = (_F & CF) | SZHV_dec[res];
416 return res;
417 }
418
419 /***************************************************************
420 * RLCA
421 ***************************************************************/
422 #if Z180_EXACT
423 #define RLCA \
424 _A = (_A << 1) | (_A >> 7); \
425 _F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF))
426 #else
427 #define RLCA \
428 _A = (_A << 1) | (_A >> 7); \
429 _F = (_F & (SF | ZF | YF | XF | PF)) | (_A & CF)
430 #endif
431
432 /***************************************************************
433 * RRCA
434 ***************************************************************/
435 #if Z180_EXACT
436 #define RRCA \
437 _F = (_F & (SF | ZF | PF)) | (_A & (YF | XF | CF)); \
438 _A = (_A >> 1) | (_A << 7)
439 #else
440 #define RRCA \
441 _F = (_F & (SF | ZF | YF | XF | PF)) | (_A & CF); \
442 _A = (_A >> 1) | (_A << 7)
443 #endif
444
445 /***************************************************************
446 * RLA
447 ***************************************************************/
448 #if Z180_EXACT
449 #define RLA { \
450 UINT8 res = (_A << 1) | (_F & CF); \
451 UINT8 c = (_A & 0x80) ? CF : 0; \
452 _F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
453 _A = res; \
454 }
455 #else
456 #define RLA { \
457 UINT8 res = (_A << 1) | (_F & CF); \
458 UINT8 c = (_A & 0x80) ? CF : 0; \
459 _F = (_F & (SF | ZF | YF | XF | PF)) | c; \
460 _A = res; \
461 }
462 #endif
463
464 /***************************************************************
465 * RRA
466 ***************************************************************/
467 #if Z180_EXACT
468 #define RRA { \
469 UINT8 res = (_A >> 1) | (_F << 7); \
470 UINT8 c = (_A & 0x01) ? CF : 0; \
471 _F = (_F & (SF | ZF | PF)) | c | (res & (YF | XF)); \
472 _A = res; \
473 }
474 #else
475 #define RRA { \
476 UINT8 res = (_A >> 1) | (_F << 7); \
477 UINT8 c = (_A & 0x01) ? CF : 0; \
478 _F = (_F & (SF | ZF | YF | XF | PF)) | c; \
479 _A = res; \
480 }
481 #endif
482
483 /***************************************************************
484 * RRD
485 ***************************************************************/
486 #define RRD { \
487 UINT8 n = RM(_HL); \
488 WM( _HL, (n >> 4) | (_A << 4) ); \
489 _A = (_A & 0xf0) | (n & 0x0f); \
490 _F = (_F & CF) | SZP[_A]; \
491 }
492
493 /***************************************************************
494 * RLD
495 ***************************************************************/
496 #define RLD { \
497 UINT8 n = RM(_HL); \
498 WM( _HL, (n << 4) | (_A & 0x0f) ); \
499 _A = (_A & 0xf0) | (n >> 4); \
500 _F = (_F & CF) | SZP[_A]; \
501 }
502
503 /***************************************************************
504 * ADD A,n
505 ***************************************************************/
506 #if BIG_FLAGS_ARRAY
507 #define ADD(value) \
508 { \
509 UINT32 ah = _AFD & 0xff00; \
510 UINT32 res = (UINT8)((ah >> 8) + value); \
511 _F = SZHVC_add[ah | res]; \
512 _A = res; \
513 }
514 #else
515 #define ADD(value) \
516 { \
517 unsigned val = value; \
518 unsigned res = _A + val; \
519 _F = SZ[(UINT8)res] | ((res >> 8) & CF) | \
520 ((_A ^ res ^ val) & HF) | \
521 (((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
522 _A = (UINT8)res; \
523 }
524 #endif
525
526 /***************************************************************
527 * ADC A,n
528 ***************************************************************/
529 #if BIG_FLAGS_ARRAY
530 #define ADC(value) \
531 { \
532 UINT32 ah = _AFD & 0xff00, c = _AFD & 1; \
533 UINT32 res = (UINT8)((ah >> 8) + value + c); \
534 _F = SZHVC_add[(c << 16) | ah | res]; \
535 _A = res; \
536 }
537 #else
538 #define ADC(value) \
539 { \
540 unsigned val = value; \
541 unsigned res = _A + val + (_F & CF); \
542 _F = SZ[res & 0xff] | ((res >> 8) & CF) | \
543 ((_A ^ res ^ val) & HF) | \
544 (((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
545 _A = res; \
546 }
547 #endif
548
549 /***************************************************************
550 * SUB n
551 ***************************************************************/
552 #if BIG_FLAGS_ARRAY
553 #define SUB(value) \
554 { \
555 UINT32 ah = _AFD & 0xff00; \
556 UINT32 res = (UINT8)((ah >> 8) - value); \
557 _F = SZHVC_sub[ah | res]; \
558 _A = res; \
559 }
560 #else
561 #define SUB(value) \
562 { \
563 unsigned val = value; \
564 unsigned res = _A - val; \
565 _F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
566 ((_A ^ res ^ val) & HF) | \
567 (((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
568 _A = res; \
569 }
570 #endif
571
572 /***************************************************************
573 * SBC A,n
574 ***************************************************************/
575 #if BIG_FLAGS_ARRAY
576 #define SBC(value) \
577 { \
578 UINT32 ah = _AFD & 0xff00, c = _AFD & 1; \
579 UINT32 res = (UINT8)((ah >> 8) - value - c); \
580 _F = SZHVC_sub[(c<<16) | ah | res]; \
581 _A = res; \
582 }
583 #else
584 #define SBC(value) \
585 { \
586 unsigned val = value; \
587 unsigned res = _A - val - (_F & CF); \
588 _F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
589 ((_A ^ res ^ val) & HF) | \
590 (((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
591 _A = res; \
592 }
593 #endif
594
595 /***************************************************************
596 * NEG
597 ***************************************************************/
598 #define NEG { \
599 UINT8 value = _A; \
600 _A = 0; \
601 SUB(value); \
602 }
603
604 /***************************************************************
605 * DAA
606 ***************************************************************/
607 #define DAA { \
608 int idx = _A; \
609 if( _F & CF ) idx |= 0x100; \
610 if( _F & HF ) idx |= 0x200; \
611 if( _F & NF ) idx |= 0x400; \
612 _AF = DAATable[idx]; \
613 }
614
615 /***************************************************************
616 * AND n
617 ***************************************************************/
618 #define AND(value) \
619 _A &= value; \
620 _F = SZP[_A] | HF
621
622 /***************************************************************
623 * OR n
624 ***************************************************************/
625 #define OR(value) \
626 _A |= value; \
627 _F = SZP[_A]
628
629 /***************************************************************
630 * XOR n
631 ***************************************************************/
632 #define XOR(value) \
633 _A ^= value; \
634 _F = SZP[_A]
635
636 /***************************************************************
637 * CP n
638 ***************************************************************/
639 #if BIG_FLAGS_ARRAY
640 #define CP(value) \
641 { \
642 UINT32 ah = _AFD & 0xff00; \
643 UINT32 res = (UINT8)((ah >> 8) - value); \
644 _F = SZHVC_sub[ah | res]; \
645 }
646 #else
647 #define CP(value) \
648 { \
649 unsigned val = value; \
650 unsigned res = _A - val; \
651 _F = SZ[res & 0xff] | ((res >> 8) & CF) | NF | \
652 ((_A ^ res ^ val) & HF) | \
653 ((((val ^ _A) & (_A ^ res)) >> 5) & VF); \
654 }
655 #endif
656
657 /***************************************************************
658 * EX AF,AF'
659 ***************************************************************/
660 #define EX_AF { \
661 PAIR tmp; \
662 tmp = Z180.AF; Z180.AF = Z180.AF2; Z180.AF2 = tmp; \
663 }
664
665 /***************************************************************
666 * EX DE,HL
667 ***************************************************************/
668 #define EX_DE_HL { \
669 PAIR tmp; \
670 tmp = Z180.DE; Z180.DE = Z180.HL; Z180.HL = tmp; \
671 }
672
673 /***************************************************************
674 * EXX
675 ***************************************************************/
676 #define EXX { \
677 PAIR tmp; \
678 tmp = Z180.BC; Z180.BC = Z180.BC2; Z180.BC2 = tmp; \
679 tmp = Z180.DE; Z180.DE = Z180.DE2; Z180.DE2 = tmp; \
680 tmp = Z180.HL; Z180.HL = Z180.HL2; Z180.HL2 = tmp; \
681 }
682
683 /***************************************************************
684 * EX (SP),r16
685 ***************************************************************/
686 #define EXSP(DR) \
687 { \
688 PAIR tmp = { { 0, 0, 0, 0 } }; \
689 RM16( _SPD, &tmp ); \
690 WM16( _SPD, &Z180.DR ); \
691 Z180.DR = tmp; \
692 }
693
694
695 /***************************************************************
696 * ADD16
697 ***************************************************************/
698 #define ADD16(DR,SR) \
699 { \
700 UINT32 res = Z180.DR.d + Z180.SR.d; \
701 _F = (_F & (SF | ZF | VF)) | \
702 (((Z180.DR.d ^ res ^ Z180.SR.d) >> 8) & HF) | \
703 ((res >> 16) & CF); \
704 Z180.DR.w.l = (UINT16)res; \
705 }
706
707 /***************************************************************
708 * ADC r16,r16
709 ***************************************************************/
710 #define ADC16(DR) \
711 { \
712 UINT32 res = _HLD + Z180.DR.d + (_F & CF); \
713 _F = (((_HLD ^ res ^ Z180.DR.d) >> 8) & HF) | \
714 ((res >> 16) & CF) | \
715 ((res >> 8) & SF) | \
716 ((res & 0xffff) ? 0 : ZF) | \
717 (((Z180.DR.d ^ _HLD ^ 0x8000) & (Z180.DR.d ^ res) & 0x8000) >> 13); \
718 _HL = (UINT16)res; \
719 }
720
721 /***************************************************************
722 * SBC r16,r16
723 ***************************************************************/
724 #define SBC16(DR) \
725 { \
726 UINT32 res = _HLD - Z180.DR.d - (_F & CF); \
727 _F = (((_HLD ^ res ^ Z180.DR.d) >> 8) & HF) | NF | \
728 ((res >> 16) & CF) | \
729 ((res >> 8) & SF) | \
730 ((res & 0xffff) ? 0 : ZF) | \
731 (((Z180.DR.d ^ _HLD) & (_HLD ^ res) &0x8000) >> 13); \
732 _HL = (UINT16)res; \
733 }
734
735 /***************************************************************
736 * RLC r8
737 ***************************************************************/
RLC(UINT8 value)738 static INLINE UINT8 RLC(UINT8 value)
739 {
740 unsigned res = value;
741 unsigned c = (res & 0x80) ? CF : 0;
742 res = ((res << 1) | (res >> 7)) & 0xff;
743 _F = SZP[res] | c;
744 return res;
745 }
746
747 /***************************************************************
748 * RRC r8
749 ***************************************************************/
RRC(UINT8 value)750 static INLINE UINT8 RRC(UINT8 value)
751 {
752 unsigned res = value;
753 unsigned c = (res & 0x01) ? CF : 0;
754 res = ((res >> 1) | (res << 7)) & 0xff;
755 _F = SZP[res] | c;
756 return res;
757 }
758
759 /***************************************************************
760 * RL r8
761 ***************************************************************/
RL(UINT8 value)762 static INLINE UINT8 RL(UINT8 value)
763 {
764 unsigned res = value;
765 unsigned c = (res & 0x80) ? CF : 0;
766 res = ((res << 1) | (_F & CF)) & 0xff;
767 _F = SZP[res] | c;
768 return res;
769 }
770
771 /***************************************************************
772 * RR r8
773 ***************************************************************/
RR(UINT8 value)774 static INLINE UINT8 RR(UINT8 value)
775 {
776 unsigned res = value;
777 unsigned c = (res & 0x01) ? CF : 0;
778 res = ((res >> 1) | (_F << 7)) & 0xff;
779 _F = SZP[res] | c;
780 return res;
781 }
782
783 /***************************************************************
784 * SLA r8
785 ***************************************************************/
SLA(UINT8 value)786 static INLINE UINT8 SLA(UINT8 value)
787 {
788 unsigned res = value;
789 unsigned c = (res & 0x80) ? CF : 0;
790 res = (res << 1) & 0xff;
791 _F = SZP[res] | c;
792 return res;
793 }
794
795 /***************************************************************
796 * SRA r8
797 ***************************************************************/
SRA(UINT8 value)798 static INLINE UINT8 SRA(UINT8 value)
799 {
800 unsigned res = value;
801 unsigned c = (res & 0x01) ? CF : 0;
802 res = ((res >> 1) | (res & 0x80)) & 0xff;
803 _F = SZP[res] | c;
804 return res;
805 }
806
807 /***************************************************************
808 * SLL r8
809 ***************************************************************/
SLL(UINT8 value)810 static INLINE UINT8 SLL(UINT8 value)
811 {
812 unsigned res = value;
813 unsigned c = (res & 0x80) ? CF : 0;
814 res = ((res << 1) | 0x01) & 0xff;
815 _F = SZP[res] | c;
816 return res;
817 }
818
819 /***************************************************************
820 * SRL r8
821 ***************************************************************/
SRL(UINT8 value)822 static INLINE UINT8 SRL(UINT8 value)
823 {
824 unsigned res = value;
825 unsigned c = (res & 0x01) ? CF : 0;
826 res = (res >> 1) & 0xff;
827 _F = SZP[res] | c;
828 return res;
829 }
830
831 /***************************************************************
832 * BIT bit,r8
833 ***************************************************************/
834 #undef BIT
835 #define BIT(bit,reg) \
836 _F = (_F & CF) | HF | SZ_BIT[reg & (1<<bit)]
837
838 /***************************************************************
839 * BIT bit,(IX/Y+o)
840 ***************************************************************/
841 #if Z180_EXACT
842 #define BIT_XY(bit,reg) \
843 _F = (_F & CF) | HF | (SZ_BIT[reg & (1<<bit)] & ~(YF|XF)) | ((EA>>8) & (YF|XF))
844 #else
845 #define BIT_XY BIT
846 #endif
847
848 /***************************************************************
849 * RES bit,r8
850 ***************************************************************/
RES(UINT8 bit,UINT8 value)851 static INLINE UINT8 RES(UINT8 bit, UINT8 value)
852 {
853 return value & ~(1<<bit);
854 }
855
856 /***************************************************************
857 * SET bit,r8
858 ***************************************************************/
SET(UINT8 bit,UINT8 value)859 static INLINE UINT8 SET(UINT8 bit, UINT8 value)
860 {
861 return value | (1<<bit);
862 }
863
864 /***************************************************************
865 * LDI
866 ***************************************************************/
867 #if Z180_EXACT
868 #define LDI { \
869 UINT8 io = RM(_HL); \
870 WM( _DE, io ); \
871 _F &= SF | ZF | CF; \
872 if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
873 if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
874 _HL++; _DE++; _BC--; \
875 if( _BC ) _F |= VF; \
876 }
877 #else
878 #define LDI { \
879 WM( _DE, RM(_HL) ); \
880 _F &= SF | ZF | YF | XF | CF; \
881 _HL++; _DE++; _BC--; \
882 if( _BC ) _F |= VF; \
883 }
884 #endif
885
886 /***************************************************************
887 * CPI
888 ***************************************************************/
889 #if Z180_EXACT
890 #define CPI { \
891 UINT8 val = RM(_HL); \
892 UINT8 res = _A - val; \
893 _HL++; _BC--; \
894 _F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
895 if( _F & HF ) res -= 1; \
896 if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
897 if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
898 if( _BC ) _F |= VF; \
899 }
900 #else
901 #define CPI { \
902 UINT8 val = RM(_HL); \
903 UINT8 res = _A - val; \
904 _HL++; _BC--; \
905 _F = (_F & CF) | SZ[res] | ((_A ^ val ^ res) & HF) | NF; \
906 if( _BC ) _F |= VF; \
907 }
908 #endif
909
910 /***************************************************************
911 * INI
912 ***************************************************************/
913 #if Z180_EXACT
914 #define INI { \
915 UINT8 io = IN(_BC); \
916 _B--; \
917 WM( _HL, io ); \
918 _HL++; \
919 _F = SZ[_B]; \
920 if( io & SF ) _F |= NF; \
921 if( (_C + io + 1) & 0x100 ) _F |= HF | CF; \
922 if( (irep_tmp1[_C & 3][io & 3] ^ \
923 breg_tmp2[_B] ^ \
924 (_C >> 2) ^ \
925 (io >> 2)) & 1 ) \
926 _F |= PF; \
927 }
928 #else
929 #define INI { \
930 _B--; \
931 WM( _HL, IN(_BC) ); \
932 _HL++; \
933 _F = (_B) ? NF : NF | ZF; \
934 }
935 #endif
936
937 /***************************************************************
938 * OUTI
939 ***************************************************************/
940 #if Z180_EXACT
941 #define OUTI { \
942 UINT8 io = RM(_HL); \
943 _B--; \
944 OUT( _BC, io ); \
945 _HL++; \
946 _F = SZ[_B]; \
947 if( io & SF ) _F |= NF; \
948 if( (_C + io + 1) & 0x100 ) _F |= HF | CF; \
949 if( (irep_tmp1[_C & 3][io & 3] ^ \
950 breg_tmp2[_B] ^ \
951 (_C >> 2) ^ \
952 (io >> 2)) & 1 ) \
953 _F |= PF; \
954 }
955 #else
956 #define OUTI { \
957 _B--; \
958 OUT( _BC, RM(_HL) ); \
959 _HL++; \
960 _F = (_B) ? NF : NF | ZF; \
961 }
962 #endif
963
964 /***************************************************************
965 * LDD
966 ***************************************************************/
967 #if Z180_EXACT
968 #define LDD { \
969 UINT8 io = RM(_HL); \
970 WM( _DE, io ); \
971 _F &= SF | ZF | CF; \
972 if( (_A + io) & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
973 if( (_A + io) & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
974 _HL--; _DE--; _BC--; \
975 if( _BC ) _F |= VF; \
976 }
977 #else
978 #define LDD { \
979 WM( _DE, RM(_HL) ); \
980 _F &= SF | ZF | YF | XF | CF; \
981 _HL--; _DE--; _BC--; \
982 if( _BC ) _F |= VF; \
983 }
984 #endif
985
986 /***************************************************************
987 * CPD
988 ***************************************************************/
989 #if Z180_EXACT
990 #define CPD { \
991 UINT8 val = RM(_HL); \
992 UINT8 res = _A - val; \
993 _HL--; _BC--; \
994 _F = (_F & CF) | (SZ[res] & ~(YF|XF)) | ((_A ^ val ^ res) & HF) | NF; \
995 if( _F & HF ) res -= 1; \
996 if( res & 0x02 ) _F |= YF; /* bit 1 -> flag 5 */ \
997 if( res & 0x08 ) _F |= XF; /* bit 3 -> flag 3 */ \
998 if( _BC ) _F |= VF; \
999 }
1000 #else
1001 #define CPD { \
1002 UINT8 val = RM(_HL); \
1003 UINT8 res = _A - val; \
1004 _HL--; _BC--; \
1005 _F = (_F & CF) | SZ[res] | ((_A ^ val ^ res) & HF) | NF; \
1006 if( _BC ) _F |= VF; \
1007 }
1008 #endif
1009
1010 /***************************************************************
1011 * IND
1012 ***************************************************************/
1013 #if Z180_EXACT
1014 #define IND { \
1015 UINT8 io = IN(_BC); \
1016 _B--; \
1017 WM( _HL, io ); \
1018 _HL--; \
1019 _F = SZ[_B]; \
1020 if( io & SF ) _F |= NF; \
1021 if( (_C + io - 1) & 0x100 ) _F |= HF | CF; \
1022 if( (drep_tmp1[_C & 3][io & 3] ^ \
1023 breg_tmp2[_B] ^ \
1024 (_C >> 2) ^ \
1025 (io >> 2)) & 1 ) \
1026 _F |= PF; \
1027 }
1028 #else
1029 #define IND { \
1030 _B--; \
1031 WM( _HL, IN(_BC) ); \
1032 _HL--; \
1033 _F = (_B) ? NF : NF | ZF; \
1034 }
1035 #endif
1036
1037 /***************************************************************
1038 * OUTD
1039 ***************************************************************/
1040 #if Z180_EXACT
1041 #define OUTD { \
1042 UINT8 io = RM(_HL); \
1043 _B--; \
1044 OUT( _BC, io ); \
1045 _HL--; \
1046 _F = SZ[_B]; \
1047 if( io & SF ) _F |= NF; \
1048 if( (_C + io - 1) & 0x100 ) _F |= HF | CF; \
1049 if( (drep_tmp1[_C & 3][io & 3] ^ \
1050 breg_tmp2[_B] ^ \
1051 (_C >> 2) ^ \
1052 (io >> 2)) & 1 ) \
1053 _F |= PF; \
1054 }
1055 #else
1056 #define OUTD { \
1057 _B--; \
1058 OUT( _BC, RM(_HL) ); \
1059 _HL--; \
1060 _F = (_B) ? NF : NF | ZF; \
1061 }
1062 #endif
1063
1064 /***************************************************************
1065 * LDIR
1066 ***************************************************************/
1067 #define LDIR \
1068 LDI; \
1069 if( _BC ) \
1070 { \
1071 _PC -= 2; \
1072 CC(ex,0xb0); \
1073 }
1074
1075 /***************************************************************
1076 * CPIR
1077 ***************************************************************/
1078 #define CPIR \
1079 CPI; \
1080 if( _BC && !(_F & ZF) ) \
1081 { \
1082 _PC -= 2; \
1083 CC(ex,0xb1); \
1084 }
1085
1086 /***************************************************************
1087 * INIR
1088 ***************************************************************/
1089 #define INIR \
1090 INI; \
1091 if( _B ) \
1092 { \
1093 _PC -= 2; \
1094 CC(ex,0xb2); \
1095 }
1096
1097 /***************************************************************
1098 * OTIR
1099 ***************************************************************/
1100 #define OTIR \
1101 OUTI; \
1102 if( _B ) \
1103 { \
1104 _PC -= 2; \
1105 CC(ex,0xb3); \
1106 }
1107
1108 /***************************************************************
1109 * LDDR
1110 ***************************************************************/
1111 #define LDDR \
1112 LDD; \
1113 if( _BC ) \
1114 { \
1115 _PC -= 2; \
1116 CC(ex,0xb8); \
1117 }
1118
1119 /***************************************************************
1120 * CPDR
1121 ***************************************************************/
1122 #define CPDR \
1123 CPD; \
1124 if( _BC && !(_F & ZF) ) \
1125 { \
1126 _PC -= 2; \
1127 CC(ex,0xb9); \
1128 }
1129
1130 /***************************************************************
1131 * INDR
1132 ***************************************************************/
1133 #define INDR \
1134 IND; \
1135 if( _B ) \
1136 { \
1137 _PC -= 2; \
1138 CC(ex,0xba); \
1139 }
1140
1141 /***************************************************************
1142 * OTDR
1143 ***************************************************************/
1144 #define OTDR \
1145 OUTD; \
1146 if( _B ) \
1147 { \
1148 _PC -= 2; \
1149 CC(ex,0xbb); \
1150 }
1151
1152 /***************************************************************
1153 * EI
1154 ***************************************************************/
1155 #define EI { \
1156 /* If interrupts were disabled, execute one more \
1157 * instruction and check the IRQ line. \
1158 * If not, simply set interrupt flip-flop 2 \
1159 */ \
1160 if( _IFF1 == 0 ) \
1161 { \
1162 _IFF1 = _IFF2 = 1; \
1163 _PPC = _PCD; \
1164 CALL_MAME_DEBUG; \
1165 _R++; \
1166 while( cpu_readop(_PCD) == 0xfb ) /* more EIs? */ \
1167 { \
1168 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d multiple EI opcodes at %04X\n", \
1169 cpu_getactivecpu(), _PC); \
1170 CC(op,0xfb); \
1171 _PPC =_PCD; \
1172 CALL_MAME_DEBUG; \
1173 _PC++; \
1174 _R++; \
1175 } \
1176 if( Z180.irq_state[0] != CLEAR_LINE || \
1177 Z180.request_irq >= 0 ) \
1178 { \
1179 after_EI = 1; /* avoid cycle skip hacks */ \
1180 EXEC(op,ROP()); \
1181 after_EI = 0; \
1182 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d EI takes INT0\n", cpu_getactivecpu()); \
1183 take_interrupt(Z180_INT0); \
1184 } \
1185 else if( Z180.irq_state[1] != CLEAR_LINE ) \
1186 { \
1187 after_EI = 1; /* avoid cycle skip hacks */ \
1188 EXEC(op,ROP()); \
1189 after_EI = 0; \
1190 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d EI takes INT1\n", cpu_getactivecpu()); \
1191 take_interrupt(Z180_INT1); \
1192 } \
1193 else if( Z180.irq_state[2] != CLEAR_LINE ) \
1194 { \
1195 after_EI = 1; /* avoid cycle skip hacks */ \
1196 EXEC(op,ROP()); \
1197 after_EI = 0; \
1198 log_cb(RETRO_LOG_DEBUG, LOGPRE "Z180 #%d EI takes INT2\n", cpu_getactivecpu()); \
1199 take_interrupt(Z180_INT2); \
1200 } else EXEC(op,ROP()); \
1201 } else _IFF2 = 1; \
1202 }
1203
1204 /***************************************************************
1205 * TST n
1206 ***************************************************************/
1207 #define TST(value) \
1208 _F = SZP[_A & value] | HF
1209
1210 /***************************************************************
1211 * MLT rr
1212 ***************************************************************/
1213 #define MLT(DR) { \
1214 Z180.DR.w.l = Z180.DR.b.l * Z180.DR.b.h; \
1215 }
1216
1217 /***************************************************************
1218 * OTIM
1219 ***************************************************************/
1220 #define OTIM { \
1221 _B--; \
1222 OUT( _C, RM(_HL) ); \
1223 _HL++; \
1224 _C++; \
1225 _F = (_B) ? NF : NF | ZF; \
1226 }
1227
1228 /***************************************************************
1229 * OTDM
1230 ***************************************************************/
1231 #define OTDM { \
1232 _B--; \
1233 OUT( _C, RM(_HL) ); \
1234 _HL--; \
1235 _C--; \
1236 _F = (_B) ? NF : NF | ZF; \
1237 }
1238
1239 /***************************************************************
1240 * OTIMR
1241 ***************************************************************/
1242 #define OTIMR \
1243 OTIM; \
1244 if( _B ) \
1245 { \
1246 _PC -= 2; \
1247 CC(ex,0xb3); \
1248 }
1249
1250 /***************************************************************
1251 * OTDMR
1252 ***************************************************************/
1253 #define OTDMR \
1254 OTDM; \
1255 if( _B ) \
1256 { \
1257 _PC -= 2; \
1258 CC(ex,0xb3); \
1259 }
1260
1261 /***************************************************************
1262 * OTDMR
1263 ***************************************************************/
1264 #define SLP { \
1265 z180_icount = 0; \
1266 _HALT = 2; \
1267 }
1268