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(("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(("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(("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(("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(("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(("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(("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(("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(("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 
1269