summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/z180/z180op.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/z180/z180op.c')
-rw-r--r--src/emu/cpu/z180/z180op.c520
1 files changed, 520 insertions, 0 deletions
diff --git a/src/emu/cpu/z180/z180op.c b/src/emu/cpu/z180/z180op.c
new file mode 100644
index 00000000000..2342ce06656
--- /dev/null
+++ b/src/emu/cpu/z180/z180op.c
@@ -0,0 +1,520 @@
+#if TIME_LOOP_HACKS
+
+#define CHECK_BC_LOOP \
+if( _BC > 1 && _PCD < 0xfffc ) { \
+ UINT8 op1 = cpu_readop(_PCD); \
+ UINT8 op2 = cpu_readop(_PCD+1); \
+ if( (op1==0x78 && op2==0xb1) || (op1==0x79 && op2==0xb0) ) \
+ { \
+ UINT8 op3 = cpu_readop(_PCD+2); \
+ UINT8 op4 = cpu_readop(_PCD+3); \
+ if( op3==0x20 && op4==0xfb ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x78] + \
+ cc[Z180_TABLE_op][0xb1] + \
+ cc[Z180_TABLE_op][0x20] + \
+ cc[Z180_TABLE_ex][0x20]; \
+ while( _BC > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _BC--; \
+ } \
+ } \
+ else \
+ if( op3 == 0xc2 ) \
+ { \
+ UINT8 ad1 = cpu_readop_arg(_PCD+3); \
+ UINT8 ad2 = cpu_readop_arg(_PCD+4); \
+ if( (ad1 + 256 * ad2) == (_PCD - 1) ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x78] + \
+ cc[Z180_TABLE_op][0xb1] + \
+ cc[Z180_TABLE_op][0xc2] + \
+ cc[Z180_TABLE_ex][0xc2]; \
+ while( _BC > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _BC--; \
+ } \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_DE_LOOP \
+if( _DE > 1 && _PCD < 0xfffc ) { \
+ UINT8 op1 = cpu_readop(_PCD); \
+ UINT8 op2 = cpu_readop(_PCD+1); \
+ if( (op1==0x7a && op2==0xb3) || (op1==0x7b && op2==0xb2) ) \
+ { \
+ UINT8 op3 = cpu_readop(_PCD+2); \
+ UINT8 op4 = cpu_readop(_PCD+3); \
+ if( op3==0x20 && op4==0xfb ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x7a] + \
+ cc[Z180_TABLE_op][0xb3] + \
+ cc[Z180_TABLE_op][0x20] + \
+ cc[Z180_TABLE_ex][0x20]; \
+ while( _DE > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _DE--; \
+ } \
+ } \
+ else \
+ if( op3==0xc2 ) \
+ { \
+ UINT8 ad1 = cpu_readop_arg(_PCD+3); \
+ UINT8 ad2 = cpu_readop_arg(_PCD+4); \
+ if( (ad1 + 256 * ad2) == (_PCD - 1) ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x7a] + \
+ cc[Z180_TABLE_op][0xb3] + \
+ cc[Z180_TABLE_op][0xc2] + \
+ cc[Z180_TABLE_ex][0xc2]; \
+ while( _DE > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _DE--; \
+ } \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_HL_LOOP \
+if( _HL > 1 && _PCD < 0xfffc ) { \
+ UINT8 op1 = cpu_readop(_PCD); \
+ UINT8 op2 = cpu_readop(_PCD+1); \
+ if( (op1==0x7c && op2==0xb5) || (op1==0x7d && op2==0xb4) ) \
+ { \
+ UINT8 op3 = cpu_readop(_PCD+2); \
+ UINT8 op4 = cpu_readop(_PCD+3); \
+ if( op3==0x20 && op4==0xfb ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x7c] + \
+ cc[Z180_TABLE_op][0xb5] + \
+ cc[Z180_TABLE_op][0x20] + \
+ cc[Z180_TABLE_ex][0x20]; \
+ while( _HL > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _HL--; \
+ } \
+ } \
+ else \
+ if( op3==0xc2 ) \
+ { \
+ UINT8 ad1 = cpu_readop_arg(_PCD+3); \
+ UINT8 ad2 = cpu_readop_arg(_PCD+4); \
+ if( (ad1 + 256 * ad2) == (_PCD - 1) ) \
+ { \
+ int cnt = \
+ cc[Z180_TABLE_op][0x7c] + \
+ cc[Z180_TABLE_op][0xb5] + \
+ cc[Z180_TABLE_op][0xc2] + \
+ cc[Z180_TABLE_ex][0xc2]; \
+ while( _HL > 0 && z180_icount > cnt ) \
+ { \
+ BURNODD( cnt, 4, cnt ); \
+ _HL--; \
+ } \
+ } \
+ } \
+ } \
+}
+
+#else
+
+#define CHECK_BC_LOOP
+#define CHECK_DE_LOOP
+#define CHECK_HL_LOOP
+
+#endif
+
+/**********************************************************
+ * main opcodes
+ **********************************************************/
+OP(op,00) { } /* NOP */
+OP(op,01) { _BC = ARG16(); } /* LD BC,w */
+OP(op,02) { WM( _BC, _A ); } /* LD (BC),A */
+OP(op,03) { _BC++; } /* INC BC */
+OP(op,04) { _B = INC(_B); } /* INC B */
+OP(op,05) { _B = DEC(_B); } /* DEC B */
+OP(op,06) { _B = ARG(); } /* LD B,n */
+OP(op,07) { RLCA; } /* RLCA */
+
+OP(op,08) { EX_AF; } /* EX AF,AF' */
+OP(op,09) { ADD16(HL,BC); } /* ADD HL,BC */
+OP(op,0a) { _A = RM(_BC); } /* LD A,(BC) */
+OP(op,0b) { _BC--; CHECK_BC_LOOP; } /* DEC BC */
+OP(op,0c) { _C = INC(_C); } /* INC C */
+OP(op,0d) { _C = DEC(_C); } /* DEC C */
+OP(op,0e) { _C = ARG(); } /* LD C,n */
+OP(op,0f) { RRCA; } /* RRCA */
+
+OP(op,10) { _B--; JR_COND( _B, 0x10 ); } /* DJNZ o */
+OP(op,11) { _DE = ARG16(); } /* LD DE,w */
+OP(op,12) { WM( _DE, _A ); } /* LD (DE),A */
+OP(op,13) { _DE++; } /* INC DE */
+OP(op,14) { _D = INC(_D); } /* INC D */
+OP(op,15) { _D = DEC(_D); } /* DEC D */
+OP(op,16) { _D = ARG(); } /* LD D,n */
+OP(op,17) { RLA; } /* RLA */
+
+OP(op,18) { JR(); } /* JR o */
+OP(op,19) { ADD16(HL,DE); } /* ADD HL,DE */
+OP(op,1a) { _A = RM(_DE); } /* LD A,(DE) */
+OP(op,1b) { _DE--; CHECK_DE_LOOP; } /* DEC DE */
+OP(op,1c) { _E = INC(_E); } /* INC E */
+OP(op,1d) { _E = DEC(_E); } /* DEC E */
+OP(op,1e) { _E = ARG(); } /* LD E,n */
+OP(op,1f) { RRA; } /* RRA */
+
+OP(op,20) { JR_COND( !(_F & ZF), 0x20 ); } /* JR NZ,o */
+OP(op,21) { _HL = ARG16(); } /* LD HL,w */
+OP(op,22) { EA = ARG16(); WM16( EA, &Z180.HL ); } /* LD (w),HL */
+OP(op,23) { _HL++; } /* INC HL */
+OP(op,24) { _H = INC(_H); } /* INC H */
+OP(op,25) { _H = DEC(_H); } /* DEC H */
+OP(op,26) { _H = ARG(); } /* LD H,n */
+OP(op,27) { DAA; } /* DAA */
+
+OP(op,28) { JR_COND( _F & ZF, 0x28 ); } /* JR Z,o */
+OP(op,29) { ADD16(HL,HL); } /* ADD HL,HL */
+OP(op,2a) { EA = ARG16(); RM16( EA, &Z180.HL ); } /* LD HL,(w) */
+OP(op,2b) { _HL--; CHECK_HL_LOOP; } /* DEC HL */
+OP(op,2c) { _L = INC(_L); } /* INC L */
+OP(op,2d) { _L = DEC(_L); } /* DEC L */
+OP(op,2e) { _L = ARG(); } /* LD L,n */
+OP(op,2f) { _A ^= 0xff; _F = (_F&(SF|ZF|PF|CF))|HF|NF|(_A&(YF|XF)); } /* CPL */
+
+OP(op,30) { JR_COND( !(_F & CF), 0x30 ); } /* JR NC,o */
+OP(op,31) { _SP = ARG16(); } /* LD SP,w */
+OP(op,32) { EA = ARG16(); WM( EA, _A ); } /* LD (w),A */
+OP(op,33) { _SP++; } /* INC SP */
+OP(op,34) { WM( _HL, INC(RM(_HL)) ); } /* INC (HL) */
+OP(op,35) { WM( _HL, DEC(RM(_HL)) ); } /* DEC (HL) */
+OP(op,36) { WM( _HL, ARG() ); } /* LD (HL),n */
+OP(op,37) { _F = (_F & (SF|ZF|PF)) | CF | (_A & (YF|XF)); } /* SCF */
+
+OP(op,38) { JR_COND( _F & CF, 0x38 ); } /* JR C,o */
+OP(op,39) { ADD16(HL,SP); } /* ADD HL,SP */
+OP(op,3a) { EA = ARG16(); _A = RM( EA ); } /* LD A,(w) */
+OP(op,3b) { _SP--; } /* DEC SP */
+OP(op,3c) { _A = INC(_A); } /* INC A */
+OP(op,3d) { _A = DEC(_A); } /* DEC A */
+OP(op,3e) { _A = ARG(); } /* LD A,n */
+OP(op,3f) { _F = ((_F&(SF|ZF|PF|CF))|((_F&CF)<<4)|(_A&(YF|XF)))^CF; } /* CCF */
+//OP(op,3f) { _F = ((_F & ~(HF|NF)) | ((_F & CF)<<4)) ^ CF; } /* CCF */
+
+OP(op,40) { } /* LD B,B */
+OP(op,41) { _B = _C; } /* LD B,C */
+OP(op,42) { _B = _D; } /* LD B,D */
+OP(op,43) { _B = _E; } /* LD B,E */
+OP(op,44) { _B = _H; } /* LD B,H */
+OP(op,45) { _B = _L; } /* LD B,L */
+OP(op,46) { _B = RM(_HL); } /* LD B,(HL) */
+OP(op,47) { _B = _A; } /* LD B,A */
+
+OP(op,48) { _C = _B; } /* LD C,B */
+OP(op,49) { } /* LD C,C */
+OP(op,4a) { _C = _D; } /* LD C,D */
+OP(op,4b) { _C = _E; } /* LD C,E */
+OP(op,4c) { _C = _H; } /* LD C,H */
+OP(op,4d) { _C = _L; } /* LD C,L */
+OP(op,4e) { _C = RM(_HL); } /* LD C,(HL) */
+OP(op,4f) { _C = _A; } /* LD C,A */
+
+OP(op,50) { _D = _B; } /* LD D,B */
+OP(op,51) { _D = _C; } /* LD D,C */
+OP(op,52) { } /* LD D,D */
+OP(op,53) { _D = _E; } /* LD D,E */
+OP(op,54) { _D = _H; } /* LD D,H */
+OP(op,55) { _D = _L; } /* LD D,L */
+OP(op,56) { _D = RM(_HL); } /* LD D,(HL) */
+OP(op,57) { _D = _A; } /* LD D,A */
+
+OP(op,58) { _E = _B; } /* LD E,B */
+OP(op,59) { _E = _C; } /* LD E,C */
+OP(op,5a) { _E = _D; } /* LD E,D */
+OP(op,5b) { } /* LD E,E */
+OP(op,5c) { _E = _H; } /* LD E,H */
+OP(op,5d) { _E = _L; } /* LD E,L */
+OP(op,5e) { _E = RM(_HL); } /* LD E,(HL) */
+OP(op,5f) { _E = _A; } /* LD E,A */
+
+OP(op,60) { _H = _B; } /* LD H,B */
+OP(op,61) { _H = _C; } /* LD H,C */
+OP(op,62) { _H = _D; } /* LD H,D */
+OP(op,63) { _H = _E; } /* LD H,E */
+OP(op,64) { } /* LD H,H */
+OP(op,65) { _H = _L; } /* LD H,L */
+OP(op,66) { _H = RM(_HL); } /* LD H,(HL) */
+OP(op,67) { _H = _A; } /* LD H,A */
+
+OP(op,68) { _L = _B; } /* LD L,B */
+OP(op,69) { _L = _C; } /* LD L,C */
+OP(op,6a) { _L = _D; } /* LD L,D */
+OP(op,6b) { _L = _E; } /* LD L,E */
+OP(op,6c) { _L = _H; } /* LD L,H */
+OP(op,6d) { } /* LD L,L */
+OP(op,6e) { _L = RM(_HL); } /* LD L,(HL) */
+OP(op,6f) { _L = _A; } /* LD L,A */
+
+OP(op,70) { WM( _HL, _B ); } /* LD (HL),B */
+OP(op,71) { WM( _HL, _C ); } /* LD (HL),C */
+OP(op,72) { WM( _HL, _D ); } /* LD (HL),D */
+OP(op,73) { WM( _HL, _E ); } /* LD (HL),E */
+OP(op,74) { WM( _HL, _H ); } /* LD (HL),H */
+OP(op,75) { WM( _HL, _L ); } /* LD (HL),L */
+OP(op,76) { ENTER_HALT; } /* HALT */
+OP(op,77) { WM( _HL, _A ); } /* LD (HL),A */
+
+OP(op,78) { _A = _B; } /* LD A,B */
+OP(op,79) { _A = _C; } /* LD A,C */
+OP(op,7a) { _A = _D; } /* LD A,D */
+OP(op,7b) { _A = _E; } /* LD A,E */
+OP(op,7c) { _A = _H; } /* LD A,H */
+OP(op,7d) { _A = _L; } /* LD A,L */
+OP(op,7e) { _A = RM(_HL); } /* LD A,(HL) */
+OP(op,7f) { } /* LD A,A */
+
+OP(op,80) { ADD(_B); } /* ADD A,B */
+OP(op,81) { ADD(_C); } /* ADD A,C */
+OP(op,82) { ADD(_D); } /* ADD A,D */
+OP(op,83) { ADD(_E); } /* ADD A,E */
+OP(op,84) { ADD(_H); } /* ADD A,H */
+OP(op,85) { ADD(_L); } /* ADD A,L */
+OP(op,86) { ADD(RM(_HL)); } /* ADD A,(HL) */
+OP(op,87) { ADD(_A); } /* ADD A,A */
+
+OP(op,88) { ADC(_B); } /* ADC A,B */
+OP(op,89) { ADC(_C); } /* ADC A,C */
+OP(op,8a) { ADC(_D); } /* ADC A,D */
+OP(op,8b) { ADC(_E); } /* ADC A,E */
+OP(op,8c) { ADC(_H); } /* ADC A,H */
+OP(op,8d) { ADC(_L); } /* ADC A,L */
+OP(op,8e) { ADC(RM(_HL)); } /* ADC A,(HL) */
+OP(op,8f) { ADC(_A); } /* ADC A,A */
+
+OP(op,90) { SUB(_B); } /* SUB B */
+OP(op,91) { SUB(_C); } /* SUB C */
+OP(op,92) { SUB(_D); } /* SUB D */
+OP(op,93) { SUB(_E); } /* SUB E */
+OP(op,94) { SUB(_H); } /* SUB H */
+OP(op,95) { SUB(_L); } /* SUB L */
+OP(op,96) { SUB(RM(_HL)); } /* SUB (HL) */
+OP(op,97) { SUB(_A); } /* SUB A */
+
+OP(op,98) { SBC(_B); } /* SBC A,B */
+OP(op,99) { SBC(_C); } /* SBC A,C */
+OP(op,9a) { SBC(_D); } /* SBC A,D */
+OP(op,9b) { SBC(_E); } /* SBC A,E */
+OP(op,9c) { SBC(_H); } /* SBC A,H */
+OP(op,9d) { SBC(_L); } /* SBC A,L */
+OP(op,9e) { SBC(RM(_HL)); } /* SBC A,(HL) */
+OP(op,9f) { SBC(_A); } /* SBC A,A */
+
+OP(op,a0) { AND(_B); } /* AND B */
+OP(op,a1) { AND(_C); } /* AND C */
+OP(op,a2) { AND(_D); } /* AND D */
+OP(op,a3) { AND(_E); } /* AND E */
+OP(op,a4) { AND(_H); } /* AND H */
+OP(op,a5) { AND(_L); } /* AND L */
+OP(op,a6) { AND(RM(_HL)); } /* AND (HL) */
+OP(op,a7) { AND(_A); } /* AND A */
+
+OP(op,a8) { XOR(_B); } /* XOR B */
+OP(op,a9) { XOR(_C); } /* XOR C */
+OP(op,aa) { XOR(_D); } /* XOR D */
+OP(op,ab) { XOR(_E); } /* XOR E */
+OP(op,ac) { XOR(_H); } /* XOR H */
+OP(op,ad) { XOR(_L); } /* XOR L */
+OP(op,ae) { XOR(RM(_HL)); } /* XOR (HL) */
+OP(op,af) { XOR(_A); } /* XOR A */
+
+OP(op,b0) { OR(_B); } /* OR B */
+OP(op,b1) { OR(_C); } /* OR C */
+OP(op,b2) { OR(_D); } /* OR D */
+OP(op,b3) { OR(_E); } /* OR E */
+OP(op,b4) { OR(_H); } /* OR H */
+OP(op,b5) { OR(_L); } /* OR L */
+OP(op,b6) { OR(RM(_HL)); } /* OR (HL) */
+OP(op,b7) { OR(_A); } /* OR A */
+
+OP(op,b8) { CP(_B); } /* CP B */
+OP(op,b9) { CP(_C); } /* CP C */
+OP(op,ba) { CP(_D); } /* CP D */
+OP(op,bb) { CP(_E); } /* CP E */
+OP(op,bc) { CP(_H); } /* CP H */
+OP(op,bd) { CP(_L); } /* CP L */
+OP(op,be) { CP(RM(_HL)); } /* CP (HL) */
+OP(op,bf) { CP(_A); } /* CP A */
+
+OP(op,c0) { RET_COND( !(_F & ZF), 0xc0 ); } /* RET NZ */
+OP(op,c1) { POP(BC); } /* POP BC */
+OP(op,c2) { JP_COND( !(_F & ZF) ); } /* JP NZ,a */
+OP(op,c3) { JP; } /* JP a */
+OP(op,c4) { CALL_COND( !(_F & ZF), 0xc4 ); } /* CALL NZ,a */
+OP(op,c5) { PUSH( BC ); } /* PUSH BC */
+OP(op,c6) { ADD(ARG()); } /* ADD A,n */
+OP(op,c7) { RST(0x00); } /* RST 0 */
+
+OP(op,c8) { RET_COND( _F & ZF, 0xc8 ); } /* RET Z */
+OP(op,c9) { POP(PC); z180_change_pc(_PCD); } /* RET */
+OP(op,ca) { JP_COND( _F & ZF ); } /* JP Z,a */
+OP(op,cb) { _R++; EXEC(cb,ROP()); } /* **** CB xx */
+OP(op,cc) { CALL_COND( _F & ZF, 0xcc ); } /* CALL Z,a */
+OP(op,cd) { CALL(); } /* CALL a */
+OP(op,ce) { ADC(ARG()); } /* ADC A,n */
+OP(op,cf) { RST(0x08); } /* RST 1 */
+
+OP(op,d0) { RET_COND( !(_F & CF), 0xd0 ); } /* RET NC */
+OP(op,d1) { POP(DE); } /* POP DE */
+OP(op,d2) { JP_COND( !(_F & CF) ); } /* JP NC,a */
+OP(op,d3) { unsigned n = ARG() | (_A << 8); OUT( n, _A ); } /* OUT (n),A */
+OP(op,d4) { CALL_COND( !(_F & CF), 0xd4 ); } /* CALL NC,a */
+OP(op,d5) { PUSH( DE ); } /* PUSH DE */
+OP(op,d6) { SUB(ARG()); } /* SUB n */
+OP(op,d7) { RST(0x10); } /* RST 2 */
+
+OP(op,d8) { RET_COND( _F & CF, 0xd8 ); } /* RET C */
+OP(op,d9) { EXX; } /* EXX */
+OP(op,da) { JP_COND( _F & CF ); } /* JP C,a */
+OP(op,db) { unsigned n = ARG() | (_A << 8); _A = IN( n ); } /* IN A,(n) */
+OP(op,dc) { CALL_COND( _F & CF, 0xdc ); } /* CALL C,a */
+OP(op,dd) { _R++; EXEC(dd,ROP()); } /* **** DD xx */
+OP(op,de) { SBC(ARG()); } /* SBC A,n */
+OP(op,df) { RST(0x18); } /* RST 3 */
+
+OP(op,e0) { RET_COND( !(_F & PF), 0xe0 ); } /* RET PO */
+OP(op,e1) { POP(HL); } /* POP HL */
+OP(op,e2) { JP_COND( !(_F & PF) ); } /* JP PO,a */
+OP(op,e3) { EXSP(HL); } /* EX HL,(SP) */
+OP(op,e4) { CALL_COND( !(_F & PF), 0xe4 ); } /* CALL PO,a */
+OP(op,e5) { PUSH( HL ); } /* PUSH HL */
+OP(op,e6) { AND(ARG()); } /* AND n */
+OP(op,e7) { RST(0x20); } /* RST 4 */
+
+OP(op,e8) { RET_COND( _F & PF, 0xe8 ); } /* RET PE */
+OP(op,e9) { _PC = _HL; z180_change_pc(_PCD); } /* JP (HL) */
+OP(op,ea) { JP_COND( _F & PF ); } /* JP PE,a */
+OP(op,eb) { EX_DE_HL; } /* EX DE,HL */
+OP(op,ec) { CALL_COND( _F & PF, 0xec ); } /* CALL PE,a */
+OP(op,ed) { _R++; EXEC(ed,ROP()); } /* **** ED xx */
+OP(op,ee) { XOR(ARG()); } /* XOR n */
+OP(op,ef) { RST(0x28); } /* RST 5 */
+
+OP(op,f0) { RET_COND( !(_F & SF), 0xf0 ); } /* RET P */
+OP(op,f1) { POP(AF); } /* POP AF */
+OP(op,f2) { JP_COND( !(_F & SF) ); } /* JP P,a */
+OP(op,f3) { _IFF1 = _IFF2 = 0; } /* DI */
+OP(op,f4) { CALL_COND( !(_F & SF), 0xf4 ); } /* CALL P,a */
+OP(op,f5) { PUSH( AF ); } /* PUSH AF */
+OP(op,f6) { OR(ARG()); } /* OR n */
+OP(op,f7) { RST(0x30); } /* RST 6 */
+
+OP(op,f8) { RET_COND( _F & SF, 0xf8 ); } /* RET M */
+OP(op,f9) { _SP = _HL; } /* LD SP,HL */
+OP(op,fa) { JP_COND(_F & SF); } /* JP M,a */
+OP(op,fb) { EI; } /* EI */
+OP(op,fc) { CALL_COND( _F & SF, 0xfc ); } /* CALL M,a */
+OP(op,fd) { _R++; EXEC(fd,ROP()); } /* **** FD xx */
+OP(op,fe) { CP(ARG()); } /* CP n */
+OP(op,ff) { RST(0x38); } /* RST 7 */
+
+
+static void take_interrupt(int irq)
+{
+ int irq_vector;
+
+ /* there isn't a valid previous program counter */
+ _PPC = -1;
+
+ /* Check if processor was halted */
+ LEAVE_HALT;
+
+ /* Clear both interrupt flip flops */
+ _IFF1 = _IFF2 = 0;
+
+ if( irq == Z180_INT0 )
+ {
+ /* Daisy chain mode? If so, call the requesting device */
+ if (Z180.daisy)
+ irq_vector = z80daisy_call_ack_device(Z180.daisy);
+
+ /* else call back the cpu interface to retrieve the vector */
+ else
+ irq_vector = (*Z180.irq_callback)(0);
+
+ LOG(("Z180 #%d single int. irq_vector $%02x\n", cpu_getactivecpu(), irq_vector));
+
+ /* Interrupt mode 2. Call [Z180.I:databyte] */
+ if( _IM == 2 )
+ {
+ irq_vector = (irq_vector & 0xff) + (_I << 8);
+ PUSH( PC );
+ RM16( irq_vector, &Z180.PC );
+ LOG(("Z180 #%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, _PCD));
+ /* CALL opcode timing */
+ z180_icount -= cc[Z180_TABLE_op][0xcd];
+ }
+ else
+ /* Interrupt mode 1. RST 38h */
+ if( _IM == 1 )
+ {
+ LOG(("Z180 #%d IM1 $0038\n",cpu_getactivecpu() ));
+ PUSH( PC );
+ _PCD = 0x0038;
+ /* RST $38 + 'interrupt latency' cycles */
+ z180_icount -= cc[Z180_TABLE_op][0xff] - cc[Z180_TABLE_ex][0xff];
+ }
+ else
+ {
+ /* Interrupt mode 0. We check for CALL and JP instructions, */
+ /* if neither of these were found we assume a 1 byte opcode */
+ /* was placed on the databus */
+ LOG(("Z180 #%d IM0 $%04x\n",cpu_getactivecpu() , irq_vector));
+ switch (irq_vector & 0xff0000)
+ {
+ case 0xcd0000: /* call */
+ PUSH( PC );
+ _PCD = irq_vector & 0xffff;
+ /* CALL $xxxx + 'interrupt latency' cycles */
+ z180_icount -= cc[Z180_TABLE_op][0xcd] - cc[Z180_TABLE_ex][0xff];
+ break;
+ case 0xc30000: /* jump */
+ _PCD = irq_vector & 0xffff;
+ /* JP $xxxx + 2 cycles */
+ z180_icount -= cc[Z180_TABLE_op][0xc3] - cc[Z180_TABLE_ex][0xff];
+ break;
+ default: /* rst (or other opcodes?) */
+ PUSH( PC );
+ _PCD = irq_vector & 0x0038;
+ /* RST $xx + 2 cycles */
+ z180_icount -= cc[Z180_TABLE_op][_PCD] - cc[Z180_TABLE_ex][_PCD];
+ break;
+ }
+ }
+ }
+ else
+ {
+ irq_vector = (IO(Z180_IL) & Z180_IL_IL) + (irq - Z180_INT1) * 2;
+ irq_vector = (_I << 8) + (irq_vector & 0xff);
+ PUSH( PC );
+ RM16( irq_vector, &Z180.PC );
+ LOG(("Z180 #%d INT%d [$%04x] = $%04x\n", cpu_getactivecpu(), irq, irq_vector, _PCD));
+ /* CALL opcode timing */
+ z180_icount -= cc[Z180_TABLE_op][0xcd];
+ }
+ z180_change_pc(_PCD);
+
+
+}
+