Esempio n. 1
0
void load_eventqueue_infos(char *buf)
{
    int len = 0;
    int i=0;
	
	clear_queue();

	//load the stack with the addresses of available slots
	for (i =0; i < QUEUE_SIZE; i++)
	{
		qstack[i] = &qbase[i];
	}

    while (*((unsigned int*)&buf[len]) != 0xFFFFFFFF)
    {
        int type = *((unsigned int*)&buf[len]);
        unsigned int count = *((unsigned int*)&buf[len+4]);
        
		switch (type)
		{
			#ifdef USE_COMPARE
			case COMPARE_INT:	add_interupt_event_count(COMPARE_INT, count); break;
			#endif
			#ifdef USE_SPECIAL
			case SPECIAL_INT:	add_interupt_event_count(SPECIAL_INT, count); break;
			#endif
			#ifdef USE_CHECK
			case CHECK_INT:	add_interupt_event_count(CHECK_INT, count); break;
			#endif
			default: add_interupt_event_count(type, count);
		}        
		len += 8;
    }
}
Esempio n. 2
0
void init_interupt(void)
{
 	if (qbase != NULL) free(qbase);
	qbase = (interupt_queue *) malloc(sizeof(interupt_queue) * QUEUE_SIZE );
	memset(qbase,0,sizeof(interupt_queue) * QUEUE_SIZE );
    qstackindex=0;
	int i=0;

	//load the stack with the addresses of available slots
	for (i =0; i < QUEUE_SIZE; i++)
	{
		qstack[i] = &qbase[i];
	}
#ifdef USE_SPECIAL
	SPECIAL_done = 1;
#endif
    next_vi = next_interupt = 5000;
    vi_register.vi_delay = next_vi;
    vi_field = 0;
    //clear_queue();
    add_interupt_event_count(VI_INT, next_vi);
#ifdef USE_SPECIAL
    add_interupt_event_count(SPECIAL_INT, 0);
#endif
}
Esempio n. 3
0
void init_interupt(usf_state_t * state)
{
    state->SPECIAL_done = 1;

    state->g_vi.delay = state->g_vi.next_vi = 5000;

    clear_queue(state);
    add_interupt_event_count(state, VI_INT, state->g_vi.next_vi);
    add_interupt_event_count(state, SPECIAL_INT, 0);
}
Esempio n. 4
0
void init_interupt(void)
{
   SPECIAL_done = 1;

   g_vi.delay = g_vi.next_vi = 5000;

   clear_queue();
   add_interupt_event_count(VI_INT, g_vi.next_vi);
   add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 5
0
void init_interupt()
{
    SPECIAL_done = 1;
    next_vi = next_interupt = 5000;
    vi_register.vi_delay = next_vi;
    vi_field = 0;
    clear_queue();
    add_interupt_event_count(VI_INT, next_vi);
    add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 6
0
void translate_event_queue(unsigned long base)
{
  interupt_queue *aux;
  remove_event(COMPARE_INT);
  remove_event(SPECIAL_INT);
  aux=q;
  while (aux != NULL) {
    aux->count = (aux->count - Count)+base;
    aux = aux->next;
  }
  add_interupt_event_count(COMPARE_INT, Compare);
  add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 7
0
void translate_event_queue(unsigned int base)
{
   struct node *e;

   remove_event(COMPARE_INT);
   remove_event(SPECIAL_INT);

   for(e = q.first; e != NULL; e = e->next)
      e->data.count = (e->data.count - g_cp0_regs[CP0_COUNT_REG]) + base;

   add_interupt_event_count(COMPARE_INT, g_cp0_regs[CP0_COMPARE_REG]);
   add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 8
0
void init_interupt()
{
  SPECIAL_done = 1;
  next_vi = next_interupt = 5000;
  vi_register.vi_delay = next_vi;
  vi_field = 0;
  if (qbase != NULL) free(qbase);
  qbase = (interupt_queue *) malloc(sizeof(interupt_queue) * QUEUE_SIZE );
  memset(qbase,0,sizeof(interupt_queue) * QUEUE_SIZE );
  qstackindex=0;
  clear_queue();
  add_interupt_event_count(VI_INT, next_vi);
  add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 9
0
void translate_event_queue(usf_state_t * state, unsigned int base)
{
    struct node* e;

    remove_event(state, COMPARE_INT);
    remove_event(state, SPECIAL_INT);

    for(e = state->q.first; e != NULL; e = e->next)
    {
        e->data.count = (e->data.count - state->g_cp0_regs[CP0_COUNT_REG]) + base;
    }
    add_interupt_event_count(state, COMPARE_INT, state->g_cp0_regs[CP0_COMPARE_REG]);
    add_interupt_event_count(state, SPECIAL_INT, 0);
}
Esempio n. 10
0
void load_eventqueue_infos(char *buf)
{
    int len = 0;
    //clear_queue();

	if (qbase != NULL) free(qbase);
	qbase = (interupt_queue *) malloc(sizeof(interupt_queue) * QUEUE_SIZE );
	memset(qbase,0,sizeof(interupt_queue) * QUEUE_SIZE );
	qstackindex=0;
    
	int i=0;

	//load the stack with the addresses of available slots
	for (i =0; i < QUEUE_SIZE; i++)
	{
		qstack[i] = &qbase[i];
	}

    while (*((unsigned int*)&buf[len]) != 0xFFFFFFFF)
    {
        int type = *((unsigned int*)&buf[len]);
        unsigned int count = *((unsigned int*)&buf[len+4]);
        add_interupt_event_count(type, count);
        len += 8;
    }
}
Esempio n. 11
0
static void special_int_handler(void)
{
   if (g_cp0_regs[CP0_COUNT_REG] > UINT32_C(0x10000000))
      return;

   SPECIAL_done = 1;
   remove_interupt_event();
   add_interupt_event_count(SPECIAL_INT, 0);
}
Esempio n. 12
0
static void compare_int_handler(void)
{
   remove_interupt_event();
   g_cp0_regs[CP0_COUNT_REG]+=count_per_op;
   add_interupt_event_count(COMPARE_INT, g_cp0_regs[CP0_COMPARE_REG]);
   g_cp0_regs[CP0_COUNT_REG]-=count_per_op;

   raise_maskable_interrupt(UINT32_C(0x8000));
}
Esempio n. 13
0
static void special_int_handler(usf_state_t * state)
{
    if (state->g_cp0_regs[CP0_COUNT_REG] > 0x10000000)
        return;

    state->SPECIAL_done = 1;
    remove_interupt_event(state);
    add_interupt_event_count(state, SPECIAL_INT, 0);
}
Esempio n. 14
0
static void compare_int_handler(usf_state_t * state)
{
    remove_interupt_event(state);
    state->g_cp0_regs[CP0_COUNT_REG]+=state->count_per_op;
    add_interupt_event_count(state, COMPARE_INT, state->g_cp0_regs[CP0_COMPARE_REG]);
    state->g_cp0_regs[CP0_COUNT_REG]-=state->count_per_op;

    if (state->enablecompare)
        raise_maskable_interrupt(state, 0x8000);
}
Esempio n. 15
0
// load the queue (for save states)
void load_eventqueue_infos(char *buf)
{
  unsigned int len = 0, type = 0, count = 0;
  clear_queue();
  while (*((unsigned long*)&buf[len]) != 0xFFFFFFFF) {
    type  = *((unsigned long*)&buf[len]);
    count = *((unsigned long*)&buf[len+4]);
    add_interupt_event_count(type, count);
    len += 8;
  }
}
Esempio n. 16
0
void load_eventqueue_infos(usf_state_t * state, char *buf)
{
    int len = 0;
    clear_queue(state);
    while (*((unsigned int*)&buf[len]) != 0xFFFFFFFF)
    {
        int type = *((unsigned int*)&buf[len]);
        unsigned int count = *((unsigned int*)&buf[len+4]);
        add_interupt_event_count(state, type, count);
        len += 8;
    }
}
Esempio n. 17
0
void translate_event_queue(unsigned int base)
{
    interupt_queue *aux;
    remove_event(COMPARE_INT);
    remove_event(SPECIAL_INT);
    aux=q;
    while (aux != NULL)
    {
#ifdef NEW_COUNT
		aux->count = ((aux->count - Count)+base)& 0x7FFFFFFF;
#else
        aux->count = (aux->count - Count)+base;
#endif
        aux = aux->next;
    }
#ifdef USE_COMPARE
    add_interupt_event_count(COMPARE_INT, Compare);
#endif
#ifdef USE_SPECIAL
    add_interupt_event_count(SPECIAL_INT, 0);
#endif
}
void ai_end_of_dma_event(struct ai_controller* ai, unsigned int ai_event)
{
    if (ai->regs[AI_STATUS_REG] & 0x80000000) // full
    {
        ai->regs[AI_STATUS_REG] &= ~0x80000000;
        ai->fifo[0].delay = ai->fifo[1].delay;
        ai->fifo[0].length = ai->fifo[1].length;
        add_interupt_event_count(AI_INT, ai_event+ai->fifo[1].delay);
    }
    else
    {
        ai->regs[AI_STATUS_REG] &= ~0x40000000;
    }

    raise_rcp_interrupt(ai->r4300, MI_INTR_AI);
}
Esempio n. 19
0
void gen_interupt(void)
{
    if (stop == 1)
    {
        vi_counter = 0; // debug
        dyna_stop();
    }

    if (!interupt_unsafe_state)
    {
        if (savestates_get_job() == savestates_job_load)
        {
            savestates_load();
            return;
        }

        if (reset_hard_job)
        {
            reset_hard();
            reset_hard_job = 0;
            return;
        }
    }
   
    if (skip_jump)
    {
        unsigned int dest = skip_jump;
        skip_jump = 0;

        if (q->count > Count || (Count - q->count) < 0x80000000)
            next_interupt = q->count;
        else
            next_interupt = 0;
        
        last_addr = dest;
        generic_jump_to(dest);
        return;
    } 

    switch(q->type)
    {
        case SPECIAL_INT:
            if (Count > 0x10000000) return;
            remove_interupt_event();
            add_interupt_event_count(SPECIAL_INT, 0);
            return;
            break;
        case VI_INT:
            if(vi_counter < 60)
            {
                if (vi_counter == 0)
                    cheat_apply_cheats(ENTRY_BOOT);
                vi_counter++;
            }
            else
            {
                cheat_apply_cheats(ENTRY_VI);
            }
            gfx.updateScreen();
#ifdef WITH_LIRC
            lircCheckInput();
#endif
            SDL_PumpEvents();

            refresh_stat();

            // if paused, poll for input events
            if(rompause)
            {
                osd_render();  // draw Paused message in case gfx.updateScreen didn't do it
                VidExt_GL_SwapBuffers();
                while(rompause)
                {
                    SDL_Delay(10);
                    SDL_PumpEvents();
#ifdef WITH_LIRC
                    lircCheckInput();
#endif //WITH_LIRC
                }
            }

            new_vi();
            if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
            else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
            next_vi += vi_register.vi_delay;
            if (vi_register.vi_status&0x40) vi_field=1-vi_field;
            else vi_field=0;

            remove_interupt_event();
            add_interupt_event_count(VI_INT, next_vi);
    
            MI_register.mi_intr_reg |= 0x08;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case COMPARE_INT:
            remove_interupt_event();
            Count+=count_per_op;
            add_interupt_event_count(COMPARE_INT, Compare);
            Count-=count_per_op;
    
            Cause = (Cause | 0x8000) & 0xFFFFFF83;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case CHECK_INT:
            remove_interupt_event();
            break;
    
        case SI_INT:
#ifdef WITH_LIRC
            lircCheckInput();
#endif //WITH_LIRC
            SDL_PumpEvents();
            PIF_RAMb[0x3F] = 0x0;
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x02;
            si_register.si_stat |= 0x1000;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case PI_INT:
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x10;
            pi_register.read_pi_status_reg &= ~3;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case AI_INT:
            if (ai_register.ai_status & 0x80000000) // full
            {
                unsigned int ai_event = get_event(AI_INT);
                remove_interupt_event();
                ai_register.ai_status &= ~0x80000000;
                ai_register.current_delay = ai_register.next_delay;
                ai_register.current_len = ai_register.next_len;
                add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
         
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            else
            {
                remove_interupt_event();
                ai_register.ai_status &= ~0x40000000;

                //-------
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            break;

        case SP_INT:
            remove_interupt_event();
            sp_register.sp_status_reg |= 0x203;
            // sp_register.sp_status_reg |= 0x303;
    
            if (!(sp_register.sp_status_reg & 0x40)) return; // !intr_on_break
            MI_register.mi_intr_reg |= 0x01;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case DP_INT:
            remove_interupt_event();
            dpc_register.dpc_status &= ~2;
            dpc_register.dpc_status |= 0x81;
            MI_register.mi_intr_reg |= 0x20;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;

        case HW2_INT:
            // Hardware Interrupt 2 -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS, and SR, set IM2
            Status = (Status & ~0x00380000) | 0x1000;
            Cause = (Cause | 0x1000) & 0xFFFFFF83;
            /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the
             * interpreter or dynarec
             */
            break;

        case NMI_INT:
            // Non Maskable Interrupt -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR
            Status = (Status & ~0x00380000) | 0x00500004;
            Cause  = 0x00000000;
            // simulate the soft reset code which would run from the PIF ROM
            r4300_reset_soft();
            // clear all interrupts, reset interrupt counters back to 0
            Count = 0;
            vi_counter = 0;
            init_interupt();
            // clear the audio status register so that subsequent write_ai() calls will work properly
            ai_register.ai_status = 0;
            // set ErrorEPC with the last instruction address
            ErrorEPC = PC->addr;
            // reset the r4300 internal state
            if (r4300emu != CORE_PURE_INTERPRETER)
            {
                // clear all the compiled instruction blocks and re-initialize
                free_blocks();
                init_blocks();
            }
            // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags
            if(delay_slot==1 || delay_slot==3)
            {
                ErrorEPC-=4;
            }
            delay_slot = 0;
            dyna_interp = 0;
            // set next instruction address to reset vector
            last_addr = 0xa4000040;
            generic_jump_to(0xa4000040);
            return;

        default:
            DebugMessage(M64MSG_ERROR, "Unknown interrupt queue event type %.8X.", q->type);
            remove_interupt_event();
            break;
    }

#ifdef NEW_DYNAREC
    if (r4300emu == CORE_DYNAREC) {
        EPC = pcaddr;
        pcaddr = 0x80000180;
        Status |= 2;
        Cause &= 0x7FFFFFFF;
        pending_exception=1;
    } else {
        exception_general();
    }
#else
    exception_general();
#endif

    if (!interupt_unsafe_state)
    {
        if (savestates_get_job() == savestates_job_save)
        {
            savestates_save();
            return;
        }
    }
}
Esempio n. 20
0
void MTC0(void)
{
    switch(PC->f.r.nrd)
    {
    case 0:    // Index
        Index = rrt & 0x8000003F;
        if ((Index & 0x3F) > 31)
        {
            DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31");
            stop=1;
        }
        break;
    case 1:    // Random
        break;
    case 2:    // EntryLo0
        EntryLo0 = rrt & 0x3FFFFFFF;
        break;
    case 3:    // EntryLo1
        EntryLo1 = rrt & 0x3FFFFFFF;
        break;
    case 4:    // Context
        Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0);
        break;
    case 5:    // PageMask
        PageMask = rrt & 0x01FFE000;
        break;
    case 6:    // Wired
        Wired = rrt;
        Random = 31;
        break;
    case 8:    // BadVAddr
        break;
    case 9:    // Count
        update_count();
        if (next_interupt <= Count) gen_interupt();
        debug_count += Count;
        translate_event_queue(rrt & 0xFFFFFFFF);
        Count = rrt & 0xFFFFFFFF;
        debug_count -= Count;
        break;
    case 10:   // EntryHi
        EntryHi = rrt & 0xFFFFE0FF;
        break;
    case 11:   // Compare
        update_count();
        remove_event(COMPARE_INT);
        add_interupt_event_count(COMPARE_INT, (unsigned int)rrt);
        Compare = rrt;
        Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear
        break;
    case 12:   // Status
        if((rrt & 0x04000000) != (Status & 0x04000000))
        {
            shuffle_fpr_data(Status, rrt);
            set_fpr_pointers(rrt);
        }
        Status = rrt;
        PC++;
        check_interupt();
        update_count();
        if (next_interupt <= Count) gen_interupt();
        PC--;
        break;
    case 13:   // Cause
        if (rrt!=0)
        {
            DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value");
            stop = 1;
        }
        else Cause = rrt;
        break;
    case 14:   // EPC
        EPC = rrt;
        break;
    case 15:  // PRevID
        break;
    case 16:  // Config
        Config = rrt;
        break;
    case 18:  // WatchLo
        WatchLo = rrt & 0xFFFFFFFF;
        break;
    case 19:  // WatchHi
        WatchHi = rrt & 0xFFFFFFFF;
        break;
    case 27:  // CacheErr
        break;
    case 28:  // TagLo
        TagLo = rrt & 0x0FFFFFC0;
        break;
    case 29: // TagHi
        TagHi =0;
        break;
    default:
        DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", PC->f.r.nrd);
        stop=1;
    }
    PC++;
}
Esempio n. 21
0
void gen_interupt()
{
   //if (!skip_jump)
     //printf("interrupt:%x (%x)\n", q->type, Count);
   if (stop == 1) dyna_stop();
   if (savestates_job & LOADSTATE) 
     {
	savestates_load();
	savestates_job &= ~LOADSTATE;
	return;
     }
   
   if (skip_jump /*&& !dynacore*/)
     {
	if (q->count > Count || (Count - q->count) < 0x80000000)
	  next_interupt = q->count;
	else
	  next_interupt = 0;
	if (interpcore)
	  {
	     /*if ((Cause & (2 << 2)) && (Cause & 0x80000000))
	       interp_addr = skip_jump+4;
	     else*/
	       interp_addr = skip_jump;
	     last_addr = interp_addr;
	  }
	else
	  {
	     /*if ((Cause & (2 << 2)) && (Cause & 0x80000000))
	       jump_to(skip_jump+4);
	     else*/
	     unsigned long dest = skip_jump;
	     skip_jump=0;
	     jump_to(dest);
	     last_addr = PC->addr;
	  }
	skip_jump=0;
	return;
     } 
   
   switch(q->type)
     {
      case SPECIAL_INT:
	if (Count > 0x10000000) return;
	remove_interupt_event();
	add_interupt_event_count(SPECIAL_INT, 0);
	return;
	break;
	
      case VI_INT:
#ifdef VCR_SUPPORT
	VCR_updateScreen();
#else
	updateScreen();
#endif
#ifndef __WIN32__
	SDL_PumpEvents();
	refresh_stat();
#endif
	new_vi();
	if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
	else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
	next_vi += vi_register.vi_delay;
	if (vi_register.vi_status&0x40) vi_field=1-vi_field;
	else vi_field=0;
	
	remove_interupt_event();
	add_interupt_event_count(VI_INT, next_vi);
	
	MI_register.mi_intr_reg |= 0x08;
	if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	  Cause = (Cause | 0x400) & 0xFFFFFF83;
	else
	  return;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      case COMPARE_INT:
	remove_interupt_event();
	Count+=2;
	add_interupt_event_count(COMPARE_INT, Compare);
	Count-=2;
	
	Cause = (Cause | 0x8000) & 0xFFFFFF83;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      case CHECK_INT:
	remove_interupt_event();
	break;
	
      case SI_INT:
#ifndef __WIN32__
	SDL_PumpEvents();
#endif
	PIF_RAMb[0x3F] = 0x0;
	remove_interupt_event();
	MI_register.mi_intr_reg |= 0x02;
	si_register.si_status |= 0x1000;
	if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	  Cause = (Cause | 0x400) & 0xFFFFFF83;
	else
	  return;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      case PI_INT:
	remove_interupt_event();
	MI_register.mi_intr_reg |= 0x10;
	pi_register.read_pi_status_reg &= ~3;
	if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	  Cause = (Cause | 0x400) & 0xFFFFFF83;
	else
	  return;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      case AI_INT:
	if (ai_register.ai_status & 0x80000000) // full
	  {
	     unsigned long ai_event = get_event(AI_INT);
	     remove_interupt_event();
	     ai_register.ai_status &= ~0x80000000;
	     ai_register.current_delay = ai_register.next_delay;
	     ai_register.current_len = ai_register.next_len;
	     //add_interupt_event(AI_INT, ai_register.next_delay/**2*/);
	     add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
	     
	     MI_register.mi_intr_reg |= 0x04;
	     if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	       Cause = (Cause | 0x400) & 0xFFFFFF83;
	     else
	       return;
	     if ((Status & 7) != 1) return;
	     if (!(Status & Cause & 0xFF00)) return;
	  }
	else
	  {
	     remove_interupt_event();
	     ai_register.ai_status &= ~0x40000000;

	     //-------
	     MI_register.mi_intr_reg |= 0x04;
	      if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	      Cause = (Cause | 0x400) & 0xFFFFFF83;
	      else
	      return;
	      if ((Status & 7) != 1) return;
	      if (!(Status & Cause & 0xFF00)) return;
	     //return;
	  }
	break;
	
      case SP_INT:
	remove_interupt_event();
	sp_register.sp_status_reg |= 0x303;
	//sp_register.signal1 = 1;
	sp_register.signal2 = 1;
	sp_register.broke = 1;
	sp_register.halt = 1;
	
	if (!sp_register.intr_break) return;
	MI_register.mi_intr_reg |= 0x01;
	if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	  Cause = (Cause | 0x400) & 0xFFFFFF83;
	else
	  return;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      case DP_INT:
	remove_interupt_event();
	dpc_register.dpc_status &= ~2;
	dpc_register.dpc_status |= 0x81;
	MI_register.mi_intr_reg |= 0x20;
	if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
	  Cause = (Cause | 0x400) & 0xFFFFFF83;
	else
	  return;
	if ((Status & 7) != 1) return;
	if (!(Status & Cause & 0xFF00)) return;
	break;
	
      default:
	remove_interupt_event();
	break;
     }
   exception_general();
   if (savestates_job & SAVESTATE) 
     {
	savestates_save();
	savestates_job &= ~SAVESTATE;
     }

#ifdef __WIN32__
	extern BOOL emu_paused;
     while(emu_paused)
     {
		Sleep(10);
//		viStatusChanged();
////		processDList();
//		processRDPList();
//		updateScreen();

		processLuaMessages();
	 }
#endif
}
Esempio n. 22
0
void gen_interupt()
{
  if (stop == 1) {
    dyna_stop();
  }

  if (savestates_job & LOADSTATE) {
    savestates_load();
    savestates_job &= ~LOADSTATE;
    return;
  }
  if (skip_jump) {
    if (q->count > Count || (Count - q->count) < 0x80000000) {
      next_interupt = q->count;
    }
    else {
      next_interupt = 0;
    }
    interp_addr = skip_jump;
    last_addr = interp_addr;
    skip_jump=0;
    return;
  } 

  switch(q->type) {
    case SPECIAL_INT:
      if (Count > 0x10000000) {
        return;
      }
      remove_interupt_event();
      add_interupt_event_count(SPECIAL_INT, 0);
      return;
    break;
    case VI_INT:
      updateScreen();
#ifdef PROFILE
      refresh_stat();
#endif
      new_vi();
      vi_register.vi_delay = (vi_register.vi_v_sync == 0) ? 500000 : ((vi_register.vi_v_sync + 1)*1500);
      next_vi += vi_register.vi_delay;
      vi_field = (vi_register.vi_status&0x40) ? 1-vi_field : 0; 
      remove_interupt_event();
      add_interupt_event_count(VI_INT, next_vi);
  
      MI_register.mi_intr_reg |= 0x08;
      if(!chk_status(1)) {
        return;
      }
    break;
  
    case COMPARE_INT:
      remove_interupt_event();
      Count+=2;
      add_interupt_event_count(COMPARE_INT, Compare);
      Count-=2;
  
      Cause = (Cause | 0x8000) & 0xFFFFFF83;
      if(!chk_status(0)) {
        return;
      }
    break;
  
    case CHECK_INT:
      remove_interupt_event();
    break;
  
    case SI_INT:
      PIF_RAMb[0x3F] = 0x0;
      remove_interupt_event();
      MI_register.mi_intr_reg |= 0x02;
      si_register.si_status |= 0x1000;
      if(!chk_status(1)) {
        return;
      }
    break;
  
    case PI_INT:
      remove_interupt_event();
      MI_register.mi_intr_reg |= 0x10;
      pi_register.read_pi_status_reg &= ~3;
      if(!chk_status(1)) {
        return;
      }
    break;
  
    case AI_INT:
      if (ai_register.ai_status & 0x80000000) { // full
        unsigned long ai_event = get_event(AI_INT);
        remove_interupt_event();
        ai_register.ai_status &= ~0x80000000;
        ai_register.current_delay = ai_register.next_delay;
        ai_register.current_len = ai_register.next_len;
        add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
      }
      else {
        remove_interupt_event();
        ai_register.ai_status &= ~0x40000000;
      }
      MI_register.mi_intr_reg |= 0x04;
      if(!chk_status(1)) {
        return;
      }
    break;

    default:
      remove_interupt_event();
    break;
  }
  exception_general();
   
  if (savestates_job & SAVESTATE) {
    savestates_save();
    savestates_job &= ~SAVESTATE;
  }
}
Esempio n. 23
0
void MTC0(void)
{
    switch(PC->f.r.nrd)
    {
    case 0:    // Index
        Index = rrt & 0x8000003F;
        if ((Index & 0x3F) > 31)
        {
            printf ("il y a plus de 32 TLB\n");
            stop=1;
        }
        break;
    case 1:    // Random
        break;
    case 2:    // EntryLo0
        EntryLo0 = rrt & 0x3FFFFFFF;
        break;
    case 3:    // EntryLo1
        EntryLo1 = rrt & 0x3FFFFFFF;
        break;
    case 4:    // Context
        Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0);
        break;
    case 5:    // PageMask
        PageMask = rrt & 0x01FFE000;
        break;
    case 6:    // Wired
        Wired = rrt;
        Random = 31;
        break;
    case 8:    // BadVAddr
        break;
    case 9:    // Count
        update_count();
        //if (next_interupt <= Count) gen_interupt();
        debug_count += Count;
        translate_event_queue(rrt & 0xFFFFFFFF);
        Count = rrt & 0xFFFFFFFF;
        debug_count -= Count;
        break;
    case 10:   // EntryHi
        EntryHi = rrt & 0xFFFFE0FF;
        break;
    case 11:   // Compare
        update_count();
        remove_event(COMPARE_INT);
        add_interupt_event_count(COMPARE_INT, (unsigned int)rrt);
        Compare = rrt;
        Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear
        break;
    case 12:   // Status
        if((rrt & 0x04000000) != (Status & 0x04000000))
        {
            if (rrt & 0x04000000)
            {
                int i;
                for (i=0; i<32; i++)
                {
                    reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
                    reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
                }
            }
            else
            {
                int i;
                for (i=0; i<32; i++)
                {
                    if(!(i&1))
                        reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
#ifndef _BIG_ENDIAN
                    reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
#else
                    reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
#endif
                }
            }
        }
        Status = rrt;
        //WTF? This screws up the count...
        //PC++;
        check_interupt();
        update_count();
        //if (next_interupt <= Count) gen_interupt();
        //PC--;
        break;
    case 13:   // Cause
        if (rrt!=0)
        {
            printf("écriture dans Cause\n");
            stop = 1;
        }
        else Cause = rrt;
        break;
    case 14:   // EPC
        EPC = rrt;
        break;
    case 15:  // PRevID
        break;
    case 16:  // Config
        Config = rrt;
        break;
    case 18:  // WatchLo
        WatchLo = rrt & 0xFFFFFFFF;
        break;
    case 19:  // WatchHi
        WatchHi = rrt & 0xFFFFFFFF;
        break;
    case 27:  // CacheErr
        break;
    case 28:  // TagLo
        TagLo = rrt & 0x0FFFFFC0;
        break;
    case 29: // TagHi
        TagHi =0;
        break;
    default:
        printf("unknown mtc0 write : %d\n", PC->f.r.nrd);
        stop=1;
    }
    PC++;
}
Esempio n. 24
0
File: cop0.c Progetto: RDCH106/Not64
void MTC0()
{
   switch(PC->f.r.nrd)
     {
      case 0:    // Index
	Index = rrt & 0x8000003F;
	if ((Index & 0x3F) > 31) 
	  {
	     printf ("il y a plus de 32 TLB\n");
	     stop=1;
	  }
	break;
      case 1:    // Random
	break;
      case 2:    // EntryLo0
	EntryLo0 = rrt & 0x3FFFFFFF;
	break;
      case 3:    // EntryLo1
 	EntryLo1 = rrt & 0x3FFFFFFF;
	break;
      case 4:    // Context
	Context = (rrt & 0xFF800000) | (Context & 0x007FFFF0);
	break;
      case 5:    // PageMask
	PageMask = rrt & 0x01FFE000;
	break;
      case 6:    // Wired
	Wired = rrt;
	Random = 31;
	break;
      case 8:    // BadVAddr
	break;
      case 9:    // Count
	update_count();
	if (next_interupt <= Count) gen_interupt();
	translate_event_queue(rrt & 0xFFFFFFFF);
	Count = rrt & 0xFFFFFFFF;
	break;
      case 10:   // EntryHi
	EntryHi = rrt & 0xFFFFE0FF;
	break;
      case 11:   // Compare
	update_count();
	remove_event(COMPARE_INT);
	add_interupt_event_count(COMPARE_INT, (unsigned long)rrt);
	Compare = rrt;
	Cause = Cause & 0xFFFF7FFF; //Timer interupt is clear
	break;
      case 12:   // Status
	if((rrt & 0x04000000) != (Status & 0x04000000))
	  {
	     shuffle_fpr_data(Status, rrt);
	     set_fpr_pointers(rrt);
	  }
	Status = rrt;
	update_count();
	PC++;
	check_interupt();
	if (next_interupt <= Count) gen_interupt();
	PC--;
	break;
      case 13:   // Cause
	if (rrt!=0)
	  {
	     printf("écriture dans Cause\n");
	     stop = 1;
	  }
	else Cause = rrt;
	break;
      case 14:   // EPC
	EPC = rrt;
	break;
      case 15:  // PRevID
	break;
      case 16:  // Config
	Config = rrt;
	break;
      case 18:  // WatchLo
	WatchLo = rrt & 0xFFFFFFFF;
	break;
      case 19:  // WatchHi
	WatchHi = rrt & 0xFFFFFFFF;
	break;
      case 27:  // CacheErr
	break;
      case 28:  // TagLo
	TagLo = rrt & 0x0FFFFFC0;
	break;
      case 29: // TagHi
	TagHi =0;
	break;
      default:
	printf("unknown mtc0 write : %d\n", PC->f.r.nrd);
	stop=1;
     }
   PC++;
}
Esempio n. 25
0
void add_interupt_event(int type, unsigned int delay)
{
   add_interupt_event_count(type, g_cp0_regs[CP0_COUNT_REG] + delay);
}
Esempio n. 26
0
void gen_interupt()
{

    if(!__emulation_run)
      stop = 1;
      
    if (stop == 1)
    {
        vi_counter = 0; // debug
        dyna_stop();
    }
    if (savestates_job & LOADSTATE) 
    {
        savestates_load();
        savestates_job &= ~LOADSTATE;
        return;
    }
   
    if (skip_jump)
    {
        if (q->count > Count || (Count - q->count) < 0x80000000)
            next_interupt = q->count;
        else
            next_interupt = 0;
        if (interpcore)
        {
             interp_addr = skip_jump;
             last_addr = interp_addr;
        }
        else
        {
            unsigned int dest = skip_jump;
            skip_jump=0;
            jump_to(dest);
            last_addr = PC->addr;
        }
        skip_jump=0;
        return;
    } 

    switch(q->type)
    {
        case SPECIAL_INT:
            if (Count > 0x10000000) return;
            remove_interupt_event();
            add_interupt_event_count(SPECIAL_INT, 0);
            return;
            break;
        case VI_INT:
            if(vi_counter < 60)
            {
                if (vi_counter == 0)
                    cheat_apply_cheats(ENTRY_BOOT);
                vi_counter++;
            }
            else
            {
                cheat_apply_cheats(ENTRY_VI);
            }
            updateScreen();
#ifdef WITH_LIRC
            lircCheckInput();
#endif
            SDL_PumpEvents();
            refresh_stat();

            // if paused, poll for input events
            if(rompause)
            {
                osd_render();  // draw Paused message in case updateScreen didn't do it
                SDL_GL_SwapBuffers();
                while(rompause)
                {
#ifdef __WIN32__
                    Sleep(10);
#else
                    struct timespec ts;
                    ts.tv_sec = 0;
                    ts.tv_nsec = 10000000;
                    nanosleep(&ts, NULL); // sleep for 10 milliseconds
#endif
                    SDL_PumpEvents();
#ifdef WITH_LIRC
                    lircCheckInput();
#endif //WITH_LIRC
                }
            }

            new_vi();
            if (vi_register.vi_v_sync == 0) vi_register.vi_delay = 500000;
            else vi_register.vi_delay = ((vi_register.vi_v_sync + 1)*1500);
            next_vi += vi_register.vi_delay;
            if (vi_register.vi_status&0x40) vi_field=1-vi_field;
            else vi_field=0;

            remove_interupt_event();
            add_interupt_event_count(VI_INT, next_vi);
    
            MI_register.mi_intr_reg |= 0x08;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case COMPARE_INT:
            remove_interupt_event();
            Count+=2;
            add_interupt_event_count(COMPARE_INT, Compare);
            Count-=2;
    
            Cause = (Cause | 0x8000) & 0xFFFFFF83;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case CHECK_INT:
            remove_interupt_event();
            break;
    
        case SI_INT:
#ifdef WITH_LIRC
            lircCheckInput();
#endif //WITH_LIRC
            SDL_PumpEvents();
            PIF_RAMb[0x3F] = 0x0;
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x02;
            si_register.si_stat |= 0x1000;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case PI_INT:
            remove_interupt_event();
            MI_register.mi_intr_reg |= 0x10;
            pi_register.read_pi_status_reg &= ~3;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case AI_INT:
            if (ai_register.ai_status & 0x80000000) // full
            {
                unsigned int ai_event = get_event(AI_INT);
                remove_interupt_event();
                ai_register.ai_status &= ~0x80000000;
                ai_register.current_delay = ai_register.next_delay;
                ai_register.current_len = ai_register.next_len;
                add_interupt_event_count(AI_INT, ai_event+ai_register.next_delay);
         
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            else
            {
                remove_interupt_event();
                ai_register.ai_status &= ~0x40000000;

                //-------
                MI_register.mi_intr_reg |= 0x04;
                if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                    Cause = (Cause | 0x400) & 0xFFFFFF83;
                else
                    return;
                if ((Status & 7) != 1) return;
                if (!(Status & Cause & 0xFF00)) return;
            }
            break;

        case SP_INT:
            remove_interupt_event();
            sp_register.sp_status_reg |= 0x303;
            //sp_register.signal1 = 1;
            sp_register.signal2 = 1;
            sp_register.broke = 1;
            sp_register.halt = 1;
    
            if (!sp_register.intr_break) return;
            MI_register.mi_intr_reg |= 0x01;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;
    
        case DP_INT:
            remove_interupt_event();
            dpc_register.dpc_status &= ~2;
            dpc_register.dpc_status |= 0x81;
            MI_register.mi_intr_reg |= 0x20;
            if (MI_register.mi_intr_reg & MI_register.mi_intr_mask_reg)
                Cause = (Cause | 0x400) & 0xFFFFFF83;
            else
                return;
            if ((Status & 7) != 1) return;
            if (!(Status & Cause & 0xFF00)) return;
            break;

        case HW2_INT:
            // Hardware Interrupt 2 -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS, and SR, set IM2
            Status = (Status & ~0x00380000) | 0x1000;
            Cause = (Cause | 0x1000) & 0xFFFFFF83;
            /* the exception_general() call below will jump to the interrupt vector (0x80000180) and setup the
             * interpreter or dynarec
             */
            break;

        case NMI_INT:
            // Non Maskable Interrupt -- remove interrupt event from queue
            remove_interupt_event();
            // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR
            Status = (Status & ~0x00380000) | 0x00500004;
            Cause  = 0x00000000;
            // simulate the soft reset code which would run from the PIF ROM
            r4300_reset_soft();
            // clear all interrupts, reset interrupt counters back to 0
            Count = 0;
            vi_counter = 0;
            init_interupt();
            // clear the audio status register so that subsequent write_ai() calls will work properly
            ai_register.ai_status = 0;
            // reset the r4300 internal state
            if (interpcore) /* pure interpreter only */
            {
                // set ErrorEPC with last instruction address and set next instruction address to reset vector
                ErrorEPC = interp_addr;
                interp_addr = 0xa4000040;
                last_addr = interp_addr;
            }
            else  /* decode-cached interpreter or dynamic recompiler */
            {
                int i;
                // clear all the compiled instruction blocks
                for (i=0; i<0x100000; i++)
                {
                    if (blocks[i])
                    {
                        if (blocks[i]->block) { free(blocks[i]->block); blocks[i]->block = NULL; }
                        if (blocks[i]->code) { free(blocks[i]->code); blocks[i]->code = NULL; }
                        if (blocks[i]->jumps_table) { free(blocks[i]->jumps_table); blocks[i]->jumps_table = NULL; }
                        if (blocks[i]->riprel_table) { free(blocks[i]->riprel_table); blocks[i]->riprel_table = NULL; }
                        free(blocks[i]);
                        blocks[i] = NULL;
                    }
                }
                // re-initialize
                init_blocks();
                // jump to the start
                ErrorEPC = PC->addr;
                jump_to(0xa4000040);
                last_addr = PC->addr;
            }
            // adjust ErrorEPC if we were in a delay slot, and clear the delay_slot and dyna_interp flags
            if(delay_slot==1 || delay_slot==3)
            {
                ErrorEPC-=4;
            }
            delay_slot = 0;
            dyna_interp = 0;
            return;

        default:
            remove_interupt_event();
            break;
    }

#ifdef NEW_DYNAREC
    EPC = pcaddr;
    pcaddr = 0x80000180;
    Status |= 2;
    Cause &= 0x7FFFFFFF;
    pending_exception=1;
#else
    exception_general();
#endif

    if (savestates_job & SAVESTATE) 
    {
        savestates_save();
        savestates_job &= ~SAVESTATE;
    }
}
Esempio n. 27
0
void add_interupt_event(usf_state_t * state, int type, unsigned int delay)
{
    add_interupt_event_count(state, type, state->g_cp0_regs[CP0_COUNT_REG] + delay);
}