static void nmi_int_handler(void)
{
    // Non Maskable Interrupt -- remove interrupt event from queue
    remove_interupt_event();
    // setup r4300 Status flags: reset TS and SR, set BEV, ERL, and SR
    g_cp0_regs[CP0_STATUS_REG] = (g_cp0_regs[CP0_STATUS_REG] & ~UINT32_C(0x00380000)) | UINT32_C(0x00500004);
    g_cp0_regs[CP0_CAUSE_REG]  = 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
    g_cp0_regs[CP0_COUNT_REG] = 0;
    g_gs_vi_counter = 0;
    init_interupt();
    // clear the audio status register so that subsequent write_ai() calls will work properly
    g_ai.regs[AI_STATUS_REG] = 0;
    // set ErrorEPC with the last instruction address
    g_cp0_regs[CP0_ERROREPC_REG] = 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)
    {
        g_cp0_regs[CP0_ERROREPC_REG]-=4;
    }
    delay_slot = 0;
    dyna_interp = 0;
    // set next instruction address to reset vector
    last_addr = UINT32_C(0xa4000040);
    generic_jump_to(UINT32_C(0xa4000040));
}
Beispiel #2
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;
    }
}
Beispiel #3
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;
        }
    }
}
Beispiel #4
0
int main(int argc, char* argv[])
{
	struct sigaction sa;

	sa.sa_flags = SA_SIGINFO | SA_NODEFER;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = handler;

	sigaction(SIGSEGV, &sa, NULL);
	sigaction(SIGABRT, &sa, NULL);
	sigaction(SIGILL, &sa, NULL);
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGFPE, &sa, NULL);

	printf("R4300 Recompiler\n\n");
#ifndef TEST
	printf("Opening %s\n",argv[1]);
#endif

	FILE *fPtr;
	uint32_t romlength = 0U;

#ifndef TEST
	if (argc <= 1) fPtr = fopen("m64p_test_rom.v64", "rb");
	else fPtr = fopen(argv[1], "rb");

 	if (fPtr == NULL) return 2;

	fseek(fPtr, 0L, SEEK_END);
	romlength = ftell(fPtr);
	fseek(fPtr, 0L, SEEK_SET);
#else
	romlength = 2000U;
#endif

	if (mmap((uint32_t*)(MMAP_BASE)
			, MMAP_BASE_SIZE + romlength
			, PROT_READ|PROT_WRITE|PROT_EXEC
			, MAP_PRIVATE| MAP_FIXED | MAP_ANONYMOUS
			, -1
			, 0 ) != (uint32_t*)(MMAP_BASE))
	{
		printf("Could not mmap\n");
		return 1;
	}

	if (mmap((uint32_t*)(MMAP_PIF_BOOT_ROM)
				, 4096
				, PROT_READ|PROT_WRITE|PROT_EXEC
				, MAP_PRIVATE| MAP_FIXED | MAP_ANONYMOUS
				, -1
				, 0 ) != (uint32_t*)(MMAP_PIF_BOOT_ROM))
		{
			printf("Could not mmap PIF area\n");
			return 1;
		}

#ifdef TEST
	//Generate helper functions
	GenerateCodeSegmentData(romlength);

	//Start testing
	Translation_Test(&segmentData);
#else
	unsigned char imagetype;

	m64p_rom_header ROM_HEADER;

	if (fread((uint32_t*)ROM_ADDRESS , 1, romlength, fPtr) != romlength)
	{
		printf("could not read ROM\n");
		return 3;
	}

	swap_rom((unsigned char*)ROM_ADDRESS, &imagetype, romlength);

	memcpy(&ROM_HEADER, (uint32_t*)ROM_ADDRESS, sizeof(m64p_rom_header));

    ROM_PARAMS.systemtype = rom_country_code_to_system_type(ROM_HEADER.Country_code);

	printf("Name: %s\n", ROM_HEADER.Name);
	printf("Rom size: %ld bytes (or %ld Mb or %ld Megabits)\n", romlength, romlength/1024/1024, romlength/1024/1024*8);
	printf("ClockRate = %x\n", sl(ROM_HEADER.ClockRate));
	printf("Version: %x\n", sl(ROM_HEADER.Release));
	printf("PC = 0x%x\n\n", sl((unsigned int)ROM_HEADER.PC));

	int x;

#if 1
	for (x=0; x< romlength/4; x++)
		*((uint32_t*)ROM_ADDRESS + x) = sl(*((uint32_t*)ROM_ADDRESS + x));
#endif

#if 0
	for (x=0x40/4; x< 200; x++ )
	{
		mips_print((uint32_t)((uint32_t*)ROM_ADDRESS + x), *((uint32_t*)ROM_ADDRESS + x));
	}

	printf("----------------------------\n");
#endif

	//Find all code where we don't know which registers are used
#if 0
	printf("Unknown register usage on these instructions:\n\n");
	for (x=0x40/4; x< romlength/4; x++ )
	{
		uint32_t temp;
		if (ops_regs_input(((uint32_t*)ROM_ADDRESS)[x],&temp,&temp,&temp) == 2
				|| ops_regs_output(((uint32_t*)ROM_ADDRESS)[x],&temp,&temp,&temp) == 2) mips_print((uint32_t*)ROM_ADDRESS + x, ((uint32_t*)ROM_ADDRESS)[x]);
	}

	printf("----------------------------\n");
#endif

	GenerateCodeSegmentData(romlength);

#if 0
	printf("MIPS Address            Length   Regs-cpu   fpu      sp     used Next       Block type 2=end,3=br\n");

	nextCodeSeg = segmentData->StaticSegments;
	int count =0;
	while (nextCodeSeg != NULL && count < 20)
	{
		count++;

		if (nextCodeSeg->MIPSReturnRegister)
		{
			printf("0x%08X 0x%08X %5d      0x%08X %08X %03X     %2d     r%d\n",
				(uint32_t)nextCodeSeg->MIPScode,
				(uint32_t)(nextCodeSeg->MIPScode+nextCodeSeg->MIPScodeLen),
				nextCodeSeg->MIPScodeLen,
				nextCodeSeg->MIPSRegistersUsed[0],
				nextCodeSeg->MIPSRegistersUsed[1],
				nextCodeSeg->MIPSRegistersUsed[2],
				nextCodeSeg->MIPSRegistersUsedCount,
				nextCodeSeg->MIPSReturnRegister);
		}
		else
		{
			printf("0x%08X 0x%08X %5d      0x%08X %08X %02X     %2d   0x%08X %d\n",
				(uint32_t)nextCodeSeg->MIPScode,
				(uint32_t)(nextCodeSeg->MIPScode+nextCodeSeg->MIPScodeLen),
				nextCodeSeg->MIPScodeLen,
				nextCodeSeg->MIPSRegistersUsed[0],
				nextCodeSeg->MIPSRegistersUsed[1],
				nextCodeSeg->MIPSRegistersUsed[2],
				nextCodeSeg->MIPSRegistersUsedCount,
				(uint32_t)nextCodeSeg->MIPSnextInstructionIndex,
				nextCodeSeg->Type);
		}

		nextCodeSeg = nextCodeSeg->next;
	}
	printf("----------------------------\n");
#endif

	printf("%d code segments generated\n", segmentData.count);

	printf("&segmentData.dbgCurrentSegment = 0x%08x\n", (uint32_t)&segmentData.dbgCurrentSegment);

// Instruction Counts for input ROM
#if 0
	code_seg_t* nextCodeSeg;

	uint32_t ins_count[sizeof_mips_op_t];
	uint32_t ins_count_total=0;
	memset(ins_count,0,sizeof(ins_count));

	nextCodeSeg = segmentData.StaticSegments;
	while (nextCodeSeg)
	{
		for (x=0; x < nextCodeSeg->MIPScodeLen; x++)
		{
			ins_count[STRIP(ops_type(*(nextCodeSeg->MIPScode + x)))] ++;
			ins_count_total++;
		}

		nextCodeSeg = nextCodeSeg->next;
	}

	for (x=0; x < sizeof_mips_op_t; x++)
	{
		if (ins_count[x])
		{
			printf("%-9s %7d (%2.2f%%)\n",Instruction_ascii[x], ins_count[x], (double)ins_count[x] * 100 / ins_count_total);
		}
	}
	printf("----------------------------\n");
#endif

	r4300_reset_hard();
	r4300_reset_soft();
	printf("\nFinished processing ROM\n");

#endif

	while (Debugger_start(&segmentData, NULL, NULL));


	// Clean up Recompiler
	freeCodeSegmentData();

	munmap((uint32_t*)MMAP_BASE, MMAP_BASE_SIZE + romlength);
	munmap((uint32_t*)MMAP_PIF_BOOT_ROM, 4096);

	printf("\nEND\n");
	return 0;
}
Beispiel #5
0
/*********************************************************************************************************
* emulation thread - runs the core
*/
m64p_error main_run(void)
{
    VILimit = (float) GetVILimit();
    VILimitMilliseconds = (double) 1000.0/VILimit; 

    /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */
    r4300emu = ConfigGetParamInt(g_CoreConfig, "R4300Emulator");

    /* set some other core parameters based on the config file values */
    savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement"));
    savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot"));
    no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump");

    /* set up the SDL key repeat and event filter to catch keyboard/joystick commands for the core */
    event_initialize();

    // initialize memory, and do byte-swapping if it's not been done yet
    if (g_MemHasBeenBSwapped == 0)
    {
        init_memory(1);
        g_MemHasBeenBSwapped = 1;
    }
    else
    {
        init_memory(0);
    }

    // Attach rom to plugins
    if (!romOpen_gfx())
    {
        free_memory(); SDL_Quit(); return M64ERR_PLUGIN_FAIL;
    }
    if (!romOpen_audio())
    {
        romClosed_gfx(); free_memory(); SDL_Quit(); return M64ERR_PLUGIN_FAIL;
    }
    if (!romOpen_input())
    {
        romClosed_audio(); romClosed_gfx(); free_memory(); SDL_Quit(); return M64ERR_PLUGIN_FAIL;
    }

    if (ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay"))
    {
        // init on-screen display
        int width = 640, height = 480;
        readScreen(NULL, &width, &height, 0); // read screen to get width and height
        osd_init(width, height);
    }

    // setup rendering callback from video plugin to the core, for screenshots and On-Screen-Display
    setRenderingCallback(video_plugin_render_callback);

#ifdef WITH_LIRC
    lircStart();
#endif // WITH_LIRC

#ifdef DBG
    if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger"))
        init_debugger();
#endif

    /* Startup message on the OSD */
    osd_new_message(OSD_MIDDLE_CENTER, "Mupen64Plus Started...");

    g_EmulatorRunning = 1;
    StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING);

    /* call r4300 CPU core and run the game */
    r4300_reset_hard();
    r4300_reset_soft();
    r4300_execute();

#ifdef WITH_LIRC
    lircStop();
#endif // WITH_LIRC

#ifdef DBG
    if (g_DebuggerActive)
        destroy_debugger();
#endif

    if (ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay"))
    {
        osd_exit();
    }

    romClosed_RSP();
    romClosed_input();
    romClosed_audio();
    romClosed_gfx();
    free_memory();

    // clean up
    g_EmulatorRunning = 0;
    StateChanged(M64CORE_EMU_STATE, M64EMU_STOPPED);

    SDL_Quit();

    return M64ERR_SUCCESS;
}
Beispiel #6
0
/*********************************************************************************************************
* emulation thread - runs the core
*/
m64p_error main_init(void)
{
   size_t i;
   unsigned int disable_extra_mem;
   static int channels[] = { 0, 1, 2, 3 };
   /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */
   r4300emu = ConfigGetParamInt(g_CoreConfig, "R4300Emulator");

   /* set some other core parameters based on the config file values */
   no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump");
   disable_extra_mem = ConfigGetParamInt(g_CoreConfig, "DisableExtraMem");
#if 0
   count_per_op = ConfigGetParamInt(g_CoreConfig, "CountPerOp");
#endif

   if (count_per_op <= 0)
      count_per_op = 2;

   /* do byte-swapping if it's not been done yet */
   if (g_MemHasBeenBSwapped == 0)
   {
      swap_buffer(g_rom, 4, g_rom_size / 4);
      g_MemHasBeenBSwapped = 1;
   }

   if (g_DDMemHasBeenBSwapped == 0)
   {
      swap_buffer(g_ddrom, 4, g_ddrom_size / 4);
      g_DDMemHasBeenBSwapped = 1;
   }

   connect_all(&g_r4300, &g_dp, &g_sp,
         &g_ai, &g_pi, &g_ri, &g_si, &g_vi, &g_dd,
         g_rdram, (disable_extra_mem == 0) ? 0x800000 : 0x400000,
         g_rom, g_rom_size, g_ddrom, g_ddrom_size, g_dd_disk, g_dd_disk_size);

   init_memory();

   // Attach rom to plugins
   printf("Gfx RomOpen.\n");
   if (!gfx.romOpen())
   {
      printf("Gfx RomOpen failed.\n");
      return M64ERR_PLUGIN_FAIL;
   }
   printf("Input RomOpen.\n");
   if (!input.romOpen())
   {
      printf("Input RomOpen failed.\n");
      gfx.romClosed();
      return M64ERR_PLUGIN_FAIL;
   }

   /* connect external time source to AF_RTC component */
   g_si.pif.af_rtc.user_data = NULL;
   g_si.pif.af_rtc.get_time = get_time_using_C_localtime;

   /* connect external game controllers */
   for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i)
   {
      g_si.pif.controllers[i].user_data = &channels[i];
      g_si.pif.controllers[i].is_connected = egcvip_is_connected;
      g_si.pif.controllers[i].get_input = egcvip_get_input;
   }

   /* connect external rumblepaks */
   for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i)
   {
      g_si.pif.controllers[i].rumblepak.user_data = &channels[i];
      g_si.pif.controllers[i].rumblepak.rumble = rvip_rumble;
   }

   /* connect saved_memory.mempacks to mempaks */
   for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i)
   {
      g_si.pif.controllers[i].mempak.user_data = NULL;
      g_si.pif.controllers[i].mempak.save = dummy_save;
      g_si.pif.controllers[i].mempak.data = &saved_memory.mempack[i][0];
   }

   /* connect saved_memory.eeprom to eeprom */
   g_si.pif.eeprom.user_data = NULL;
   g_si.pif.eeprom.save = dummy_save;
   g_si.pif.eeprom.data = saved_memory.eeprom;
   if (ROM_SETTINGS.savetype != EEPROM_16KB)
   {
      /* 4kbits EEPROM */
      g_si.pif.eeprom.size = 0x200;
      g_si.pif.eeprom.id = 0x8000;
   }
   else
   {
      /* 16kbits EEPROM */
      g_si.pif.eeprom.size = 0x800;
      g_si.pif.eeprom.id = 0xc000;
   }

   /* connect saved_memory.flashram to flashram */
   g_pi.flashram.user_data = NULL;
   g_pi.flashram.save = dummy_save;
   g_pi.flashram.data = saved_memory.flashram;

   /* connect saved_memory.sram to SRAM */
   g_pi.sram.user_data = NULL;
   g_pi.sram.save = dummy_save;
   g_pi.sram.data = saved_memory.sram;

#ifdef DBG
   if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger"))
      init_debugger();
#endif

   g_EmulatorRunning = 1;
   StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING);

   /* call r4300 CPU core and run the game */
   r4300_reset_hard();
   r4300_reset_soft();
   r4300_init();


   return M64ERR_SUCCESS;
}
Beispiel #7
0
/*********************************************************************************************************
* emulation thread - runs the core
*/
m64p_error main_run(void)
{
	DebugMessage(M64MSG_STATUS, "Main Run!");
    VILimit = (float) GetVILimit();
    VILimitMilliseconds = (double) 1000.0/VILimit; 

    /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */
    r4300emu = ConfigGetParamInt(g_CoreConfig, "R4300Emulator");

    /* set some other core parameters based on the config file values */
    savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement"));
    savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot"));
    no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump");

    /* set up the SDL key repeat and event filter to catch keyboard/joystick commands for the core */
    event_initialize();

    // initialize memory, and do byte-swapping if it's not been done yet
    if (g_MemHasBeenBSwapped == 0)
    {
        init_memory(1);
        g_MemHasBeenBSwapped = 1;
    }
    else
    {
        init_memory(0);
    }

    // Attach rom to plugins
    if (!romOpen_gfx())
    {
        free_memory(); return M64ERR_PLUGIN_FAIL;
    }
    DebugMessage(M64MSG_STATUS, "Graphics Plugin Opened!");
    if (!romOpen_audio())
    {
        romClosed_gfx(); free_memory(); return M64ERR_PLUGIN_FAIL;
    }
    DebugMessage(M64MSG_STATUS, "Audio Plugin Opened!");
    if (!romOpen_input())
    {
        romClosed_audio(); romClosed_gfx(); free_memory(); return M64ERR_PLUGIN_FAIL;
    }
    DebugMessage(M64MSG_STATUS, "Input Plugin Opened!");
    printf("Plugins opened!\n");fflush(stdout);

#ifdef WITH_LIRC
    lircStart();
#endif // WITH_LIRC

#ifdef DBG
    if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger"))
        init_debugger();
#endif

    //PumpEvents();


    g_EmulatorRunning = 1;
    StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING);
    DebugMessage(M64MSG_STATUS, "Starting to reset r4300!");fflush(stdout);
    /* call r4300 CPU core and run the game */
    r4300_reset_hard();
    r4300_reset_soft();
    DebugMessage(M64MSG_STATUS, "About to execute!");
    fflush(stdout);
    r4300_execute();

#ifdef WITH_LIRC
    lircStop();
#endif // WITH_LIRC

#ifdef DBG
    if (g_DebuggerActive)
        destroy_debugger();
#endif

    romClosed_RSP();
    romClosed_input();
    romClosed_audio();
    romClosed_gfx();
    free_memory();

    // clean up
    g_EmulatorRunning = 0;
    StateChanged(M64CORE_EMU_STATE, M64EMU_STOPPED);

    //PDL_Quit();
    SDL_Quit();

    return M64ERR_SUCCESS;
}