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*/); }
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); }
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; }
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]); } }
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; } }
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++)