Beispiel #1
0
void dma_pi_read()
{
   int i;
   
   if (pi_register.pi_cart_addr_reg >= 0x08000000 &&
       pi_register.pi_cart_addr_reg < 0x08010000)
     {
	if (use_flashram != 1)
	  {
	     char *filename;
	     FILE *f;
	     filename = (char*)malloc(strlen(get_savespath())+
			       strlen(ROM_SETTINGS.goodname)+4+1);
	     strcpy(filename, get_savespath());
	     strcat(filename, ROM_SETTINGS.goodname);
	     strcat(filename, ".sra");
	     f = fopen(filename, "rb");
	     if (f)
	       {
		  fread(sram, 1, 0x8000, f);
		  fclose(f);
	       }
	     else for (i=0; i<0x8000; i++) sram[i] = 0;
	     for (i=0; i<(pi_register.pi_rd_len_reg & 0xFFFFFF)+1; i++)
	       sram[((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8]=
	       ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8];
	     f = fopen(filename, "wb");
	     fwrite(sram, 1, 0x8000, f);
	     fclose(f);
	     free(filename);
	     use_flashram = -1;
	  }
	else
	  dma_write_flashram();
     }
   else
     printf("unknown dma read\n");
   
   pi_register.read_pi_status_reg |= 1;
   update_count();
   add_interupt_event(PI_INT, 0x1000/*pi_register.pi_rd_len_reg*/);
}
Beispiel #2
0
void savestates_save()
{
	char *filename, buf[1024];
	gzFile f;
	int len, i, filename_f = 0;
   
	savestates_job_success = TRUE;
   
	if (*autoinc_save_slot)
	{
		if (++slot == 10)
		{
			slot = 0;
		}
	}
   
	if (slot <= 9)
	{
		filename = (char*)malloc(strlen(get_savespath())+
		strlen(ROM_SETTINGS.goodname)+4+1);
		strcpy(filename, get_savespath());
		strcat(filename, ROM_SETTINGS.goodname);
		strcat(filename, ".st");
		sprintf(buf, "%d", slot);
		strcat(filename, buf);
	}
	else
	{
		filename = (char*)malloc(strlen(fname)+1);
		strcpy(filename, fname);
		slot -= 10;
		filename_f = 1;
	}

	{
		char str [256];
		if(filename_f)
			sprintf(str, "saving %-200s", filename);
		else
			sprintf(str, "saving slot %d", slot);
		display_status(str);
	}
   	
	f = gzopen(filename, "wb");
	free(filename);
   
	gzwrite(f, ROM_SETTINGS.MD5, 32);
   
	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));
	gzwrite(f, rdram, 0x800000);
	gzwrite(f, SP_DMEM, 0x1000);
	gzwrite(f, SP_IMEM, 0x1000);
	gzwrite(f, PIF_RAM, 0x40);

	save_flashram_infos(buf);
	gzwrite(f, buf, 24);
   
	gzwrite(f, tlb_LUT_r, 0x400000);
	gzwrite(f, tlb_LUT_w, 0x400000);
   
	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);
	gzwrite(f, reg_cop1_fgr_64, 32*8);
	gzwrite(f, &FCR0, 4);
	gzwrite(f, &FCR31, 4);
	gzwrite(f, tlb_e, 32*sizeof(tlb));
	if (!dynacore && interpcore) 
		gzwrite(f, &interp_addr, 4);
	else 
		gzwrite(f, &PC->addr, 4);
   
	gzwrite(f, &next_interupt, 4);
	gzwrite(f, &next_vi, 4);
	gzwrite(f, &vi_field, 4);
   
	len = save_eventqueue_infos(buf);
	gzwrite(f, buf, len);

	// re-recording
	BOOL movieActive = VCR_isActive();
	gzwrite(f, &movieActive, sizeof(movieActive));
	if(movieActive)
	{
		char* movie_freeze_buf = NULL;
		unsigned long movie_freeze_size = 0;

		VCR_movieFreeze(&movie_freeze_buf, &movie_freeze_size);
		if(movie_freeze_buf)
		{
			gzwrite(f, &movie_freeze_size, sizeof(movie_freeze_size));
			gzwrite(f, movie_freeze_buf, movie_freeze_size);
			free(movie_freeze_buf);
		}
		else
		{
			fprintf(stderr, "Failed to save movie snapshot.\n");
			savestates_job_success = FALSE;
		}
	}
	// /re-recording

	gzclose(f);
}
Beispiel #3
0
void savestates_load()
{
	char *filename, buf[1024];
	gzFile f;
	int len, i;
	int filename_f = 0;

	savestates_job_success = TRUE;
   
	if (slot <= 9)
	{
		filename = (char*)malloc(strlen(get_savespath())+
		strlen(ROM_SETTINGS.goodname)+4+1);
		strcpy(filename, get_savespath());
		strcat(filename, ROM_SETTINGS.goodname);
		strcat(filename, ".st");
		sprintf(buf, "%d", slot);
		strcat(filename, buf);
	}
	else
	{
		filename = (char*)malloc(strlen(fname)+1);
		strcpy(filename, fname);
		slot -= 10;
		filename_f = 1;
	}

	{
		char str [256];
		if(filename_f)
			sprintf(str, "loading %-200s", filename);
		else
			sprintf(str, "loading slot %d", slot);
		display_status(str);
	}

	f = gzopen(filename, "rb");
   
	if (f == NULL)
	{
		printf("Savestate \"%s\" not found.\n", filename);
		free(filename);
		warn_savestate_not_exist();
		savestates_job_success = FALSE;
		return;
	}
	free(filename);
   
	gzread(f, buf, 32);
	if (memcmp(buf, ROM_SETTINGS.MD5, 32))
	{
		warn_savestate_from_another_rom();
		gzclose(f);
		savestates_job_success = FALSE;
		return;
	}
   
	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));
	gzread(f, rdram, 0x800000);
	gzread(f, SP_DMEM, 0x1000);
	gzread(f, SP_IMEM, 0x1000);
	gzread(f, PIF_RAM, 0x40);

	gzread(f, buf, 24);
	load_flashram_infos(buf);
   
	gzread(f, tlb_LUT_r, 0x400000);
	gzread(f, tlb_LUT_w, 0x400000);
   
	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
	}
	gzread(f, &lo, 8);
	gzread(f, &hi, 8);
	gzread(f, reg_cop1_fgr_64, 32*8);
	gzread(f, &FCR0, 4);
	gzread(f, &FCR31, 4);
	gzread(f, tlb_e, 32*sizeof(tlb));
	if (!dynacore && interpcore)
		gzread(f, &interp_addr, 4);
	else
	{
		int i;
		gzread(f, &len, 4);
		for (i=0; i<0x100000; i++) 
			invalid_code[i] = 1;
		jump_to(len);
	}
   
	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);
      
	BOOL movieSnapshot;
	gzread(f, &movieSnapshot, sizeof(movieSnapshot));
	if(VCR_isActive() && !movieSnapshot)
	{
		fprintf(stderr, "Can't load a non-movie snapshot while a movie is active.\n");
		savestates_job_success = FALSE;
		goto failedLoad;
	}
   
	if(movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added later on in the save format
	{
		unsigned long movieInputDataSize = 0;
		gzread(f, &movieInputDataSize, sizeof(movieInputDataSize));
		char* local_movie_data = (char*)malloc(movieInputDataSize * sizeof(char));
		int readBytes = gzread(f, local_movie_data, movieInputDataSize);
		if(readBytes != movieInputDataSize)
		{
			fprintf(stderr, "Corrupt movie snapshot.\n");
			if(local_movie_data)
				free(local_movie_data);
			savestates_job_success = FALSE;
			goto failedLoad;
		}
		int code = VCR_movieUnfreeze(local_movie_data, movieInputDataSize);
		if(local_movie_data) 
			free(local_movie_data);
		if(code != SUCCESS && !VCR_isIdle())
		{
			char errStr [1024];
			strcpy(errStr, "Failed to load movie snapshot\n");
			switch(code)
			{
				case NOT_FROM_THIS_MOVIE: 
					strcat(errStr, ";\nSnapshot not from this movie"); 
					break;
				case NOT_FROM_A_MOVIE:
					strcat(errStr, ";\nNot a movie snapshot"); 
					break;// shouldn't get here...
				case INVALID_FRAME:
					strcat(errStr, ";\nInvalid frame number");
					break;
				case WRONG_FORMAT: 
					strcat(errStr, ";\nWrong format");
					break;
			}
			strcat(errStr, ".");
			fprintf(stderr, "%s\n", errStr);
		#ifdef __WIN32__
			void ShowInfo(char *Str, ...);
			ShowInfo(errStr);
		#endif
			savestates_job_success = FALSE;
			goto failedLoad;
		}
	}
	else // loading a non-movie snapshot from a movie
	{
		if(VCR_isActive())
		{
		#ifdef __WIN32__
			MessageBox(NULL, "The movie has been stopped to load this non-movie snapshot.", "Warning", MB_OK | MB_ICONWARNING);
		#else
			printf("[VCR]: Warning: The movie has been stopped to load this non-movie snapshot.\n");
		#endif
			if(VCR_isPlaying())
				VCR_stopPlayback();
			else
				VCR_stopRecord();
		}
	}
failedLoad:

	gzclose(f);
	if (!dynacore && interpcore)
		last_addr = interp_addr;
	else
		last_addr = PC->addr;
}
void savestates_save()
{
   char *filename, buf[1024];
   gzFile f;
   int len, i;
   
   if (*autoinc_save_slot)
     {
	if (++slot == 10)
	  {
	     slot = 0;
	  }
     }
   
   if (slot <= 9)
     {
	filename = malloc(strlen(get_savespath())+
			  strlen(ROM_SETTINGS.goodname)+4+1);
	strcpy(filename, get_savespath());
	strcat(filename, ROM_SETTINGS.goodname);
	strcat(filename, ".st");
	sprintf(buf, "%d", slot);
	strcat(filename, buf);
     }
   else
     {
	filename = malloc(strlen(fname)+1);
	strcpy(filename, fname);
	slot -= 10;
     }
   	
   f = gzopen(filename, "wb");
   free(filename);
   
   gzwrite(f, ROM_SETTINGS.MD5, 32);
   
   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));
   
   gzwrite(f, rdram, 0x800000);
   gzwrite(f, SP_DMEM, 0x1000);
   gzwrite(f, SP_IMEM, 0x1000);
   gzwrite(f, PIF_RAM, 0x40);

   save_flashram_infos(buf);
   gzwrite(f, buf, 24);
   
   gzwrite(f, tlb_LUT_r, 0x100000);
   gzwrite(f, tlb_LUT_w, 0x100000);
   
   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);
   gzwrite(f, reg_cop1_fgr_64, 32*8);
   gzwrite(f, &FCR0, 4);
   gzwrite(f, &FCR31, 4);
   gzwrite(f, tlb_e, 32*sizeof(tlb));
   if (!dynacore && interpcore) gzwrite(f, &interp_addr, 4);
   else gzwrite(f, &PC->addr, 4);
   
   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);
}
void savestates_load()
{
   char *filename, buf[1024];
   gzFile f;
   int len, i;
   
   if (slot <= 9)
     {
	filename = malloc(strlen(get_savespath())+
			  strlen(ROM_SETTINGS.goodname)+4+1);
	strcpy(filename, get_savespath());
	strcat(filename, ROM_SETTINGS.goodname);
	strcat(filename, ".st");
	sprintf(buf, "%d", slot);
	strcat(filename, buf);
     }
   else
     {
	filename = malloc(strlen(fname)+1);
	strcpy(filename, fname);
	slot -= 10;
     }
   f = gzopen(filename, "rb");
   free(filename);
   
   if (f == NULL)
     {
	warn_savestate_not_exist();
	return;
     }
   
   gzread(f, buf, 32);
   if (memcmp(buf, ROM_SETTINGS.MD5, 32))
     {
	warn_savestate_from_another_rom();
	gzclose(f);
	return;
     }
   
   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));
   gzread(f, rdram, 0x800000);
   gzread(f, SP_DMEM, 0x1000);
   gzread(f, SP_IMEM, 0x1000);
   gzread(f, PIF_RAM, 0x40);

   gzread(f, buf, 24);
   load_flashram_infos(buf);
   
   gzread(f, tlb_LUT_r, 0x100000);
   gzread(f, tlb_LUT_w, 0x100000);
   
   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
     }
   gzread(f, &lo, 8);
   gzread(f, &hi, 8);
   gzread(f, reg_cop1_fgr_64, 32*8);
   gzread(f, &FCR0, 4);
   gzread(f, &FCR31, 4);
   gzread(f, tlb_e, 32*sizeof(tlb));
   if (!dynacore && interpcore) gzread(f, &interp_addr, 4);
   else
     {
	int i;
	gzread(f, &len, 4);
	for (i=0; i<0x100000; i++) invalid_code[i] = 1;
	jump_to(len);
     }
   
   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);
   if (!dynacore && interpcore)
     last_addr = interp_addr;
   else
     last_addr = PC->addr;
}
Beispiel #6
0
void EepromCommand(BYTE *Command)
{
   switch (Command[2])
     {
      case 0: // check
	if (Command[1] != 3)
	  {
	     Command[1] |= 0x40;
	     if ((Command[1] & 3) > 0)
	       Command[3] = 0;
	     if ((Command[1] & 3) > 1)
	       Command[4] = ROM_SETTINGS.eeprom_16kb == 0 ? 0x80 : 0xc0;
	     if ((Command[1] & 3) > 2)
	       Command[5] = 0;
	  }
	else
	  {
	     Command[3] = 0;
	     Command[4] = ROM_SETTINGS.eeprom_16kb == 0 ? 0x80 : 0xc0;
	     Command[5] = 0;
	  }
	break;
      case 4: // read
	  {
	     char *filename;
	     FILE *f;
	     int i;
	     filename = malloc(strlen(get_savespath())+
			       strlen(ROM_SETTINGS.goodname)+4+1);
	     strcpy(filename, get_savespath());
	     strcat(filename, ROM_SETTINGS.goodname);
	     if (UseSave == 1)
            strcat(filename, ".eep");
          else
            strcat(filename,".net");
	     f = fopen(filename, "rb");
	     if (f)
	       {
		  fread(eeprom, 1, 0x800, f);
		  fclose(f);
	       }
	     else for (i=0; i<0x800; i++) eeprom[i] = 0;
	     free(filename);
	     memcpy(&Command[4], eeprom + Command[3]*8, 8);
	  }
	break;
      case 5: // write
	  {
	     char *filename;
	     FILE *f;
	     int i;
	     filename = malloc(strlen(get_savespath())+
			       strlen(ROM_SETTINGS.goodname)+4+1);
	     strcpy(filename, get_savespath());
	     strcat(filename, ROM_SETTINGS.goodname);
	     if (UseSave == 1)
            strcat(filename, ".eep");
         else
            strcat(filename,".net");
	     f = fopen(filename, "rb");
	     if (f)
	       {
		  fread(eeprom, 1, 0x800, f);
		  fclose(f);
	       }
	     else for (i=0; i<0x800; i++) eeprom[i] = 0;
	     memcpy(eeprom + Command[3]*8, &Command[4], 8);
	     f = fopen(filename, "wb");
	     fwrite(eeprom, 1, 0x800, f);
	     fclose(f);
	     free(filename);
	  }
	break;
      default:
	printf("unknown command in EepromCommand : %x\n", Command[2]);
     }
}
Beispiel #7
0
void internal_ControllerCommand(int Control, BYTE *Command)
{
   switch (Command[2])
     {
      case 0x00: // check
      case 0xFF:
	if ((Command[1] & 0x80))
	  break;
	if (Controls[Control].Present)
	  {
	     Command[3] = 0x05;
	     Command[4] = 0x00;
	     switch(Controls[Control].Plugin)
	       {
		case PLUGIN_MEMPAK:
		  Command[5] = 1;
		  break;
		case PLUGIN_RAW:
		  Command[5] = 1;
		  break;
		default:
		  Command[5] = 0;
		  break;
	       }
	  }
	else
	  Command[1] |= 0x80;
	break;
      case 0x01:
	if (!Controls[Control].Present)
	  Command[1] |= 0x80;
	break;
      case 0x02: // read controller pack
	if (Controls[Control].Present)
	  {
	     switch(Controls[Control].Plugin)
	       {
		case PLUGIN_MEMPAK:
		    {
		       int address = (Command[3] << 8) | Command[4];
		       if (address == 0x8001)
			 {
			    memset(&Command[5], 0, 0x20);
			    Command[0x25] = mempack_crc(&Command[5]);
			 }
		       else
			 {
			    address &= 0xFFE0;
			    if (address <= 0x7FE0)
			      {
				 char *filename;
				 FILE *f;
				 filename = malloc(strlen(get_savespath())+
						   strlen(ROM_SETTINGS.goodname)+4+1);
				 strcpy(filename, get_savespath());
				 strcat(filename, ROM_SETTINGS.goodname);
				 if (UseSave == 1)
                 strcat(filename, ".mpk");
                 else
                 strcat(filename,".net");
				 f = fopen(filename, "rb");
				 if (f)
				   {
				      fread(mempack[0], 1, 0x8000, f);
				      fread(mempack[1], 1, 0x8000, f);
				      fread(mempack[2], 1, 0x8000, f);
				      fread(mempack[3], 1, 0x8000, f);
				      fclose(f);
				   }
				 else format_mempacks();
				 free(filename);
				 memcpy(&Command[5], &mempack[Control][address], 0x20);
			      }
			    else
			      {
				 memset(&Command[5], 0, 0x20);
			      }
			    Command[0x25] = mempack_crc(&Command[5]);
			 }
		    }
		  break;
		case PLUGIN_RAW:
		  if (controllerCommand) controllerCommand(Control, Command);
		  break;
		default:
		  memset(&Command[5], 0, 0x20);
		  Command[0x25] = 0;
	       }
	  }
	else
	  Command[1] |= 0x80;
	break;
      case 0x03: // write controller pack
	if (Controls[Control].Present)
	  {
	     switch(Controls[Control].Plugin)
	       {
		case PLUGIN_MEMPAK:
		    {
		       int address = (Command[3] << 8) | Command[4];
		       if (address == 0x8001) 
			 Command[0x25] = mempack_crc(&Command[5]);
		       else
			 {
			    address &= 0xFFE0;
			    if (address <= 0x7FE0)
			      {
				 char *filename;
				 FILE *f;
				 filename = malloc(strlen(get_savespath())+
						   strlen(ROM_SETTINGS.goodname)+4+1);
				 strcpy(filename, get_savespath());
				 strcat(filename, ROM_SETTINGS.goodname);
				 if (UseSave == 1)
                 strcat(filename, ".mpk");
                 else
                 strcat(filename,".net");
				 f = fopen(filename, "rb");
				 if (f)
				   {
				      fread(mempack[0], 1, 0x8000, f);
				      fread(mempack[1], 1, 0x8000, f);
				      fread(mempack[2], 1, 0x8000, f);
				      fread(mempack[3], 1, 0x8000, f);
				      fclose(f);
				   }
				 else format_mempacks();
				 memcpy(&mempack[Control][address], &Command[5], 0x20);
				 f = fopen(filename, "wb");
				 fwrite(mempack[0], 1, 0x8000, f);
				 fwrite(mempack[1], 1, 0x8000, f);
				 fwrite(mempack[2], 1, 0x8000, f);
				 fwrite(mempack[3], 1, 0x8000, f);
				 fclose(f);
				 free(filename);
			      }
			    Command[0x25] = mempack_crc(&Command[5]);
			 }
		    }
		  break;
		case PLUGIN_RAW:
		  if (controllerCommand) controllerCommand(Control, Command);
		  break;
		default:
		  Command[0x25] = mempack_crc(&Command[5]);
	       }
	  }
	else
	  Command[1] |= 0x80;
	break;
     }
}
Beispiel #8
0
void dma_pi_write()
{
   unsigned long longueur;
   int i;
   
   if (pi_register.pi_cart_addr_reg < 0x10000000)
     {
	if (pi_register.pi_cart_addr_reg >= 0x08000000 &&
	    pi_register.pi_cart_addr_reg < 0x08010000)
	  {
	     if (use_flashram != 1)
	       {
		  char *filename;
		  FILE *f;
		  int i;
		  filename = (char*)malloc(strlen(get_savespath())+
				    strlen(ROM_SETTINGS.goodname)+4+1);
		  strcpy(filename, get_savespath());
		  strcat(filename, ROM_SETTINGS.goodname);
		  strcat(filename, ".sra");
		  f = fopen(filename, "rb");
		  if (f)
		    {
		       fread(sram, 1, 0x8000, f);
		       fclose(f);
		    }
		  else for (i=0; i<0x8000; i++) sram[i] = 0x0;
		  free(filename);
		  for (i=0; i<(pi_register.pi_wr_len_reg & 0xFFFFFF)+1; i++)
		    ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
		    sram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8];
		  use_flashram = -1;
	       }
	     else
	       dma_read_flashram();
	  }
	else if (pi_register.pi_cart_addr_reg >= 0x06000000 &&
		 pi_register.pi_cart_addr_reg < 0x08000000)
	  {
	  }
	else
	  printf("unknown dma write:%x\n", (int)pi_register.pi_cart_addr_reg);
	
	pi_register.read_pi_status_reg |= 1;
	update_count();
	add_interupt_event(PI_INT, /*pi_register.pi_wr_len_reg*/0x1000);
     
	return;
     }
   
   if (pi_register.pi_cart_addr_reg >= 0x1fc00000) // for paper mario
     {
	pi_register.read_pi_status_reg |= 1;
	update_count();
	add_interupt_event(PI_INT, 0x1000);
	return;
     }
   
   longueur = (pi_register.pi_wr_len_reg & 0xFFFFFF)+1;
   i = (pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF;
   longueur = (i + longueur) > taille_rom ?
     (taille_rom - i) : longueur;
   longueur = (pi_register.pi_dram_addr_reg + longueur) > 0x7FFFFF ?
     (0x7FFFFF - pi_register.pi_dram_addr_reg) : longueur;
   
   if(i>taille_rom || pi_register.pi_dram_addr_reg > 0x7FFFFF)
     {
	pi_register.read_pi_status_reg |= 3;
	update_count();
	add_interupt_event(PI_INT, longueur/8);
	return;
     }
   
   if(!interpcore)
     {
	for (i=0; i<longueur; i++)
	  {
	     unsigned long rdram_address1 = pi_register.pi_dram_addr_reg+i+0x80000000;
	     unsigned long rdram_address2 = pi_register.pi_dram_addr_reg+i+0xa0000000;
	     
	     ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
	       rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8];
	     
	     if(!invalid_code[rdram_address1>>12])
	       if(blocks[rdram_address1>>12]->block[(rdram_address1&0xFFF)/4].ops != NOTCOMPILED)
		 invalid_code[rdram_address1>>12] = 1;
	     
	     if(!invalid_code[rdram_address2>>12])
	       if(blocks[rdram_address2>>12]->block[(rdram_address2&0xFFF)/4].ops != NOTCOMPILED)
		 invalid_code[rdram_address2>>12] = 1;
	  }
     }
   else
     {
	for (i=0; i<longueur; i++)