#include "pcfx.h"

static uint16 InterruptAsserted;
static uint16 InterruptMask;
static uint16 InterruptPriority[2];
static uint32 InterruptCache;

void PCFXIRQ_Assert(int level, bool assert)
{
 InterruptAsserted &= ~(1 << (15 - level));
 
 //printf("Assert: %d %d\n", level, assert);
 if(assert)
  InterruptAsserted |= (1 << (15 - level));

 uint32 iwithmask = InterruptAsserted &~ InterruptMask;
 InterruptCache = 0;

 for(int level = 15; level >= 8; level--)
 {
  if(iwithmask & (1 << (15 - level))) // Interrupt wanted at this level
  {
   for(int priority = 7; priority >= 0; priority--)
   {
    if(level >= 12)
    {
     if(((InterruptPriority[0] >> ((15 - level) * 3)) & 0x7) == priority)
     {
      InterruptCache = level;
      break;
     }
    }
    else // level < 12
    {
     if(((InterruptPriority[1] >> ((11 - level) * 3)) & 0x7) == priority)
     {
      InterruptCache = level;
      break;
     }
    }
   }
  }
 }

 //printf("Lovelove: %d %d\n", InterruptCache, iwithmask);
}


uint16 PCFXIRQ_Read16(uint32 A)
{
 switch(A & 0xC0)
 {
  case 0x00: puts("IRQA Read FIXME?"); return(InterruptAsserted); // Just a guess, FIXME?
  case 0x40: return(InterruptMask);
  case 0x80: return(InterruptPriority[0]);
  case 0xC0: return(InterruptPriority[1]);
 }
}

void PCFXIRQ_Write16(uint32 A, uint16 V)
{
 printf("IRQW: %08x %04x\n", A, V);
 switch(A & 0xC0)
 {
  case 0x40: InterruptMask = V; break;
  case 0x80: InterruptPriority[0] = V; break;
  case 0xC0: InterruptPriority[1] = V; break;
 }
}

uint32 PCFXIRQ_Check(void)
{
 return InterruptCache;
}
