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