コード例 #1
0
ファイル: cop0.c プロジェクト: RDCH106/n64oid
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++;
}
コード例 #2
0
ファイル: cop0.c プロジェクト: 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++;
}
コード例 #3
0
ファイル: savestates_gc.c プロジェクト: RDCH106/Not64
void savestates_load()
{
	gzFile f = NULL;
	char *filename, buf[1024];
	int len, i;
		
	/* fix the filename to %s.st%d format */
  filename = malloc(1024);
  sprintf(filename, "%s%s%s%s.st%d",(saveStateDevice==SAVESTATEDEVICE_USB)?"usb:":"sd:",
                           statespath, ROM_SETTINGS.goodname, saveregionstr(),savestates_slot);
	
	f = gzopen(filename, "rb");
	free(filename);
	
	if (!f) {
		return;
	}
	if(stop) {
	  pauseRemovalThread();
  }
  else {
    pauseAudio();
  }
  gzread(f, &rdram_register, sizeof(RDRAM_register));
	gzread(f, &MI_register, sizeof(mips_register));
	gzread(f, &pi_register, sizeof(PI_register));
	gzread(f, &sp_register, sizeof(SP_register));
	gzread(f, &rsp_register, sizeof(RSP_register));
	gzread(f, &si_register, sizeof(SI_register));
	gzread(f, &vi_register, sizeof(VI_register));
	gzread(f, &ri_register, sizeof(RI_register));
	gzread(f, &ai_register, sizeof(AI_register));
	gzread(f, &dpc_register, sizeof(DPC_register));
	gzread(f, &dps_register, sizeof(DPS_register));
#ifdef USE_EXPANSION
	gzread(f, rdram, 0x800000);
#else
  gzread(f, rdram, 0x400000);
#endif
	gzread(f, SP_DMEM, 0x1000);
	gzread(f, SP_IMEM, 0x1000);
	gzread(f, PIF_RAM, 0x40);
	gzread(f, buf, 24);
	load_flashram_infos(buf);
	
#ifndef USE_TLB_CACHE
	gzread(f, tlb_LUT_r, 0x100000);
	gzread(f, tlb_LUT_w, 0x100000);
#else
	int numNodesWritten_r=0,numNodesWritten_w=0,cntr,tlbpage,tlbvalue;	
	TLBCache_deinit();
	TLBCache_init();
	//Load number of them..
	gzread(f, &numNodesWritten_r, 4);
	for(cntr=0;cntr<numNodesWritten_r;cntr++)
	{
		gzread(f, &tlbpage, 4);
		gzread(f, &tlbvalue, 4);
		TLBCache_set_r(tlbpage,tlbvalue);
	}
	gzread(f, &numNodesWritten_w, 4);
	for(cntr=0;cntr<numNodesWritten_w;cntr++)
	{
		gzread(f, &tlbpage, 4);
		gzread(f, &tlbvalue, 4);
		TLBCache_set_w(tlbpage,tlbvalue);
	}
#endif

	gzread(f, &llbit, 4);
	gzread(f, reg, 32*8);
	for (i=0; i<32; i++) 
	{
		gzread(f, reg_cop0+i, 4);
		gzread(f, buf, 4); // for compatibility with old versions purpose
	}
	set_fpr_pointers(Status);  // Status is reg_cop0[12]
	gzread(f, &lo, 8);
	gzread(f, &hi, 8);
	gzread(f, reg_cop1_fgr_64, 32*8);
	if ((Status & 0x04000000) == 0)  // 32-bit FPR mode requires data shuffling because 64-bit layout is always stored in savestate file
		shuffle_fpr_data(0x04000000, 0);
	gzread(f, &FCR0, 4);
	gzread(f, &FCR31, 4);
	gzread(f, tlb_e, 32*sizeof(tlb));
	for (i=0; i<0x100000; i++)
		invalid_code_set(i, 1);
	gzread(f, &interp_addr, 4);       //dynarec should be ok with just this
	gzread(f, &next_interupt, 4);
	gzread(f, &next_vi, 4);
	gzread(f, &vi_field, 4);
	
	len = 0;
	while(1)
	{
		gzread(f, buf+len, 4);
		if (*((unsigned long*)&buf[len]) == 0xFFFFFFFF) break;
		gzread(f, buf+len+4, 4);
		len += 8;
	}
	load_eventqueue_infos(buf);
	
	gzclose(f);
	last_addr = interp_addr;
	if(stop) {
	  continueRemovalThread();
  }
  else {
    resumeAudio();
  }
}
コード例 #4
0
ファイル: savestates_gc.c プロジェクト: RDCH106/Not64
void savestates_save()
{ 
  gzFile f;
	char *filename, buf[1024];
  int len, i;
	
  /* fix the filename to %s.st%d format */
  filename = malloc(1024);
  sprintf(filename, "%s%s%s%s.st%d",(saveStateDevice==SAVESTATEDEVICE_USB)?"usb:":"sd:",
                           statespath, ROM_SETTINGS.goodname, saveregionstr(),savestates_slot);

	f = gzopen(filename, "wb");
  free(filename);
   	
  if(!f) {
  	return;
	}
  if(stop) {
	  pauseRemovalThread();
  }
  else {
    pauseAudio();
  }  
  gzwrite(f, &rdram_register, sizeof(RDRAM_register));
	gzwrite(f, &MI_register, sizeof(mips_register));
	gzwrite(f, &pi_register, sizeof(PI_register));
	gzwrite(f, &sp_register, sizeof(SP_register));
	gzwrite(f, &rsp_register, sizeof(RSP_register));
	gzwrite(f, &si_register, sizeof(SI_register));
	gzwrite(f, &vi_register, sizeof(VI_register));
	gzwrite(f, &ri_register, sizeof(RI_register));
	gzwrite(f, &ai_register, sizeof(AI_register));
	gzwrite(f, &dpc_register, sizeof(DPC_register));
	gzwrite(f, &dps_register, sizeof(DPS_register));
#ifdef USE_EXPANSION
	gzwrite(f, rdram, 0x800000);
#else
  gzwrite(f, rdram, 0x400000);
#endif
	gzwrite(f, SP_DMEM, 0x1000);
	gzwrite(f, SP_IMEM, 0x1000);
	gzwrite(f, PIF_RAM, 0x40);
	
	save_flashram_infos(buf);
	gzwrite(f, buf, 24);
#ifndef USE_TLB_CACHE
	gzwrite(f, tlb_LUT_r, 0x100000);		
	gzwrite(f, tlb_LUT_w, 0x100000);
#else
	//Traverse the TLB cache hash	and dump it
  TLBCache_dump_r(f);
	TLBCache_dump_w(f);
#endif

	gzwrite(f, &llbit, 4);
	gzwrite(f, reg, 32*8);
	for (i=0; i<32; i++) gzwrite(f, reg_cop0+i, 8); // *8 for compatibility with old versions purpose
	gzwrite(f, &lo, 8);
	gzwrite(f, &hi, 8);

	if ((Status & 0x04000000) == 0)
	{   // FR bit == 0 means 32-bit (MIPS I) FGR mode
		shuffle_fpr_data(0, 0x04000000);  // shuffle data into 64-bit register format for storage
		gzwrite(f, reg_cop1_fgr_64, 32*8);
		shuffle_fpr_data(0x04000000, 0);  // put it back in 32-bit mode
	}
	else
	{
		gzwrite(f, reg_cop1_fgr_64, 32*8);
	}

	gzwrite(f, &FCR0, 4);
	gzwrite(f, &FCR31, 4);
	gzwrite(f, tlb_e, 32*sizeof(tlb));
	gzwrite(f, &interp_addr, 4);    //Dynarec should be ok with just this

	gzwrite(f, &next_interupt, 4);
	gzwrite(f, &next_vi, 4);
	gzwrite(f, &vi_field, 4);
	
	len = save_eventqueue_infos(buf);
	gzwrite(f, buf, len);
	
	gzclose(f);
	if(stop) {
	  continueRemovalThread();
  }
  else {
    resumeAudio();
  }
}
コード例 #5
0
int savestates_load_m64p(const unsigned char *data, size_t size)
{
    unsigned char header[44];
    int version;
    int i;

    unsigned char *curr = (unsigned char*)data; // < HACK
    char queue[1024];

    /* Read and check Mupen64Plus magic number. */
    if(strncmp((char *)curr, savestate_magic, 8)!=0)
    {
        return 0;
    }
    curr += 8;

    version = *curr++;
    version = (version << 8) | *curr++;
    version = (version << 8) | *curr++;
    version = (version << 8) | *curr++;
    if(version != 0x00010000)
    {
        return 0;
    }

    if(memcmp((char *)curr, ROM_SETTINGS.MD5, 32))
    {
        return 0;
    }
    curr += 32;

    // Parse savestate
    rdram_register.rdram_config = GETDATA(curr, unsigned int);
    rdram_register.rdram_device_id = GETDATA(curr, unsigned int);
    rdram_register.rdram_delay = GETDATA(curr, unsigned int);
    rdram_register.rdram_mode = GETDATA(curr, unsigned int);
    rdram_register.rdram_ref_interval = GETDATA(curr, unsigned int);
    rdram_register.rdram_ref_row = GETDATA(curr, unsigned int);
    rdram_register.rdram_ras_interval = GETDATA(curr, unsigned int);
    rdram_register.rdram_min_interval = GETDATA(curr, unsigned int);
    rdram_register.rdram_addr_select = GETDATA(curr, unsigned int);
    rdram_register.rdram_device_manuf = GETDATA(curr, unsigned int);

    MI_register.w_mi_init_mode_reg = GETDATA(curr, unsigned int);
    MI_register.mi_init_mode_reg = GETDATA(curr, unsigned int);
    curr += 4; // Duplicate MI init mode flags from old implementation
    MI_register.mi_version_reg = GETDATA(curr, unsigned int);
    MI_register.mi_intr_reg = GETDATA(curr, unsigned int);
    MI_register.mi_intr_mask_reg = GETDATA(curr, unsigned int);
    MI_register.w_mi_intr_mask_reg = GETDATA(curr, unsigned int);
    curr += 8; // Duplicated MI intr flags and padding from old implementation

    pi_register.pi_dram_addr_reg = GETDATA(curr, unsigned int);
    pi_register.pi_cart_addr_reg = GETDATA(curr, unsigned int);
    pi_register.pi_rd_len_reg = GETDATA(curr, unsigned int);
    pi_register.pi_wr_len_reg = GETDATA(curr, unsigned int);
    pi_register.read_pi_status_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom1_lat_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom1_pwd_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom1_pgs_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom1_rls_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom2_lat_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom2_pwd_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom2_pgs_reg = GETDATA(curr, unsigned int);
    pi_register.pi_bsd_dom2_rls_reg = GETDATA(curr, unsigned int);

    sp_register.sp_mem_addr_reg = GETDATA(curr, unsigned int);
    sp_register.sp_dram_addr_reg = GETDATA(curr, unsigned int);
    sp_register.sp_rd_len_reg = GETDATA(curr, unsigned int);
    sp_register.sp_wr_len_reg = GETDATA(curr, unsigned int);
    sp_register.w_sp_status_reg = GETDATA(curr, unsigned int);
    sp_register.sp_status_reg = GETDATA(curr, unsigned int);
    curr += 16; // Duplicated SP flags and padding from old implementation
    sp_register.sp_dma_full_reg = GETDATA(curr, unsigned int);
    sp_register.sp_dma_busy_reg = GETDATA(curr, unsigned int);
    sp_register.sp_semaphore_reg = GETDATA(curr, unsigned int);

    rsp_register.rsp_pc = GETDATA(curr, unsigned int);
    rsp_register.rsp_ibist = GETDATA(curr, unsigned int);

    si_register.si_dram_addr = GETDATA(curr, unsigned int);
    si_register.si_pif_addr_rd64b = GETDATA(curr, unsigned int);
    si_register.si_pif_addr_wr64b = GETDATA(curr, unsigned int);
    si_register.si_stat = GETDATA(curr, unsigned int);

    vi_register.vi_status = GETDATA(curr, unsigned int);
    vi_register.vi_origin = GETDATA(curr, unsigned int);
    vi_register.vi_width = GETDATA(curr, unsigned int);
    vi_register.vi_v_intr = GETDATA(curr, unsigned int);
    vi_register.vi_current = GETDATA(curr, unsigned int);
    vi_register.vi_burst = GETDATA(curr, unsigned int);
    vi_register.vi_v_sync = GETDATA(curr, unsigned int);
    vi_register.vi_h_sync = GETDATA(curr, unsigned int);
    vi_register.vi_leap = GETDATA(curr, unsigned int);
    vi_register.vi_h_start = GETDATA(curr, unsigned int);
    vi_register.vi_v_start = GETDATA(curr, unsigned int);
    vi_register.vi_v_burst = GETDATA(curr, unsigned int);
    vi_register.vi_x_scale = GETDATA(curr, unsigned int);
    vi_register.vi_y_scale = GETDATA(curr, unsigned int);
    vi_register.vi_delay = GETDATA(curr, unsigned int);

    update_vi_status(vi_register.vi_status);
    update_vi_width(vi_register.vi_width);

    ri_register.ri_mode = GETDATA(curr, unsigned int);
    ri_register.ri_config = GETDATA(curr, unsigned int);
    ri_register.ri_current_load = GETDATA(curr, unsigned int);
    ri_register.ri_select = GETDATA(curr, unsigned int);
    ri_register.ri_refresh = GETDATA(curr, unsigned int);
    ri_register.ri_latency = GETDATA(curr, unsigned int);
    ri_register.ri_error = GETDATA(curr, unsigned int);
    ri_register.ri_werror = GETDATA(curr, unsigned int);

    ai_register.ai_dram_addr = GETDATA(curr, unsigned int);
    ai_register.ai_len = GETDATA(curr, unsigned int);
    ai_register.ai_control = GETDATA(curr, unsigned int);
    ai_register.ai_status = GETDATA(curr, unsigned int);
    ai_register.ai_dacrate = GETDATA(curr, unsigned int);
    ai_register.ai_bitrate = GETDATA(curr, unsigned int);
    ai_register.next_delay = GETDATA(curr, unsigned int);
    ai_register.next_len = GETDATA(curr, unsigned int);
    ai_register.current_delay = GETDATA(curr, unsigned int);
    ai_register.current_len = GETDATA(curr, unsigned int);
    update_ai_dacrate(ai_register.ai_dacrate);

    dpc_register.dpc_start = GETDATA(curr, unsigned int);
    dpc_register.dpc_end = GETDATA(curr, unsigned int);
    dpc_register.dpc_current = GETDATA(curr, unsigned int);
    dpc_register.w_dpc_status = GETDATA(curr, unsigned int);
    dpc_register.dpc_status = GETDATA(curr, unsigned int);
    curr += 12; // Duplicated DPC flags and padding from old implementation
    dpc_register.dpc_clock = GETDATA(curr, unsigned int);
    dpc_register.dpc_bufbusy = GETDATA(curr, unsigned int);
    dpc_register.dpc_pipebusy = GETDATA(curr, unsigned int);
    dpc_register.dpc_tmem = GETDATA(curr, unsigned int);

    dps_register.dps_tbist = GETDATA(curr, unsigned int);
    dps_register.dps_test_mode = GETDATA(curr, unsigned int);
    dps_register.dps_buftest_addr = GETDATA(curr, unsigned int);
    dps_register.dps_buftest_data = GETDATA(curr, unsigned int);

    COPYARRAY(rdram, curr, unsigned int, 0x800000/4);
    COPYARRAY(SP_DMEM, curr, unsigned int, 0x1000/4);
    COPYARRAY(SP_IMEM, curr, unsigned int, 0x1000/4);
    COPYARRAY(PIF_RAM, curr, unsigned char, 0x40);

    flashram_info.use_flashram = GETDATA(curr, int);
    flashram_info.mode = GETDATA(curr, int);
    flashram_info.status = GETDATA(curr, unsigned long long);
    flashram_info.erase_offset = GETDATA(curr, unsigned int);
    flashram_info.write_pointer = GETDATA(curr, unsigned int);

    COPYARRAY(tlb_LUT_r, curr, unsigned int, 0x100000);
    COPYARRAY(tlb_LUT_w, curr, unsigned int, 0x100000);

    llbit = GETDATA(curr, unsigned int);
    COPYARRAY(reg, curr, long long int, 32);
    COPYARRAY(reg_cop0, curr, unsigned int, 32);
    set_fpr_pointers(Status);  // Status is reg_cop0[12]
    lo = GETDATA(curr, long long int);
    hi = GETDATA(curr, long long int);
    COPYARRAY(reg_cop1_fgr_64, curr, long long int, 32);
    if ((Status & 0x04000000) == 0)  // 32-bit FPR mode requires data shuffling because 64-bit layout is always stored in savestate file
        shuffle_fpr_data(0x04000000, 0);
    FCR0 = GETDATA(curr, int);
    FCR31 = GETDATA(curr, int);

    for (i = 0; i < 32; i++)
    {
        tlb_e[i].mask = GETDATA(curr, short);
        curr += 2;
        tlb_e[i].vpn2 = GETDATA(curr, int);
        tlb_e[i].g = GETDATA(curr, char);
        tlb_e[i].asid = GETDATA(curr, unsigned char);
        curr += 2;
        tlb_e[i].pfn_even = GETDATA(curr, int);
        tlb_e[i].c_even = GETDATA(curr, char);
        tlb_e[i].d_even = GETDATA(curr, char);
        tlb_e[i].v_even = GETDATA(curr, char);
        curr++;
        tlb_e[i].pfn_odd = GETDATA(curr, int);
        tlb_e[i].c_odd = GETDATA(curr, char);
        tlb_e[i].d_odd = GETDATA(curr, char);
        tlb_e[i].v_odd = GETDATA(curr, char);
        tlb_e[i].r = GETDATA(curr, char);
   
        tlb_e[i].start_even = GETDATA(curr, unsigned int);
        tlb_e[i].end_even = GETDATA(curr, unsigned int);
        tlb_e[i].phys_even = GETDATA(curr, unsigned int);
        tlb_e[i].start_odd = GETDATA(curr, unsigned int);
        tlb_e[i].end_odd = GETDATA(curr, unsigned int);
        tlb_e[i].phys_odd = GETDATA(curr, unsigned int);
    }

#ifdef NEW_DYNAREC
    if (r4300emu == CORE_DYNAREC) {
        pcaddr = GETDATA(curr, unsigned int);
        pending_exception = 1;
        invalidate_all_pages();
    } else {