static void take_interrupt()
    {
        if( Z80.IFF1!=0)
        {
            int irq_vector;
    
           /* there isn't a valid previous program counter */
           Z80.PREPC.SetD(-1);//_PPC = -1;
    
            /* Check if processor was halted */
            if(Z80.HALT!=0) 												
            {															
    		Z80.HALT = 0;												
    		Z80.PC.AddD(1);//_PC++;
            }
            if( Z80.irq_max!=0)           /* daisy chain mode */
            {
                throw new UnsupportedOperationException("Daisy chain unimplemented");         
    /*TODO*///            if( Z80.request_irq >= 0 )
    /*TODO*///            {
    /*TODO*///                /* Clear both interrupt flip flops */
    /*TODO*///                _IFF1 = _IFF2 = 0;
    /*TODO*///                irq_vector = Z80.irq[Z80.request_irq].interrupt_entry(Z80.irq[Z80.request_irq].irq_param);
    /*TODO*///                LOG((errorlog, "Z80#%d daisy chain irq_vector $%02x\n", cpu_getactivecpu(), irq_vector));
    /*TODO*///                Z80.request_irq = -1;
    /*TODO*///            } else return;
            }
            else
            {
                
               /* Clear both interrupt flip flops */
                Z80.IFF1 = Z80.IFF2 = 0;
                /* call back the cpu interface to retrieve the vector */
                irq_vector = Z80.irq_callback.handler(0);
                if(errorlog!=null) fprintf(errorlog, "Z80#%d single int. irq_vector $%02x\n", cpu_getactivecpu(), System.identityHashCode(irq_vector));
            }
    
            /* Interrupt mode 2. Call [Z80.I:databyte] */
            if( Z80.IM == 2 )
            {
                  
    		   irq_vector = (irq_vector & 0xff) | (Z80.I << 8);
                //PUSH( PC );
                   Z80.SP.SetD((Z80.SP.D - 2) & 0xFFFF);
                   cpu_writemem16(Z80.SP.D, Z80.PC.L);
                   cpu_writemem16((int)(Z80.SP.D + 1) & 0xffff, Z80.PC.H);
    		// RM16( irq_vector, &Z80.PC );
                   Z80.PC.SetL((cpu_readmem16(irq_vector) & 0xFF)); //RM16
                   Z80.PC.SetH((cpu_readmem16((irq_vector + 1) & 0xffff)& 0xFF));
                  if(errorlog!=null) fprintf(errorlog, "Z80#%d IM2 [$%04x] = $%04x\n",cpu_getactivecpu() , irq_vector, Z80.PC.D);
                   Z80.extra_cycles += 19;
            }
            else
            {
                /* Interrupt mode 1. RST 38h */
                if( Z80.IM == 1 )
                {
                   if(errorlog!=null) fprintf(errorlog, "Z80#%d IM1 $0038\n",cpu_getactivecpu());
                   Z80.SP.SetD((Z80.SP.D - 2) & 0xFFFF);
                   cpu_writemem16(Z80.SP.D, Z80.PC.L);
                   cpu_writemem16((int)(Z80.SP.D + 1) & 0xffff, Z80.PC.H);
                   Z80.PC.SetD(0x0038);//_PCD = 0x0038;
                   Z80.extra_cycles += 11+2; /* RST $38 + 2 cycles */
                }
                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                                */
                if(errorlog!=null) fprintf(errorlog, "Z80#%d IM0 $%04x\n",cpu_getactivecpu() , irq_vector);
                switch (irq_vector & 0xff0000)
                {
                    case 0xcd0000:  /* call */
                        
                        Z80.SP.SetD((Z80.SP.D - 2) & 0xFFFF); //PUSH( PC );
                        cpu_writemem16(Z80.SP.D, Z80.PC.L);
                        cpu_writemem16((int)(Z80.SP.D + 1) & 0xffff, Z80.PC.H);
                        Z80.extra_cycles += 5;  /* CALL $xxxx cycles (JP $xxxx follows)*/
                    case 0xc30000:  /* jump */
                        Z80.PC.SetD(irq_vector & 0xffff);
                        Z80.extra_cycles += 10 + 2; /* JP $xxxx + 2 cycles */
                        break;
                    default:        /* rst */
                        Z80.SP.SetD((Z80.SP.D - 2) & 0xFFFF); //PUSH( PC );
                        cpu_writemem16(Z80.SP.D, Z80.PC.L);
                        cpu_writemem16((int)(Z80.SP.D + 1) & 0xffff, Z80.PC.H);
                        Z80.PC.SetD(irq_vector & 0x0038);
                        Z80.extra_cycles += 11 + 2; /* RST $xx + 2 cycles */
                        break;
               }
             }
            }
            change_pc(Z80.PC.D);
        }       
    }