/** * Try to figure if the RSP was launched using osSpTask* functions * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless). * * Previously, the ucode_size field was used to determine this, * but it is not robust enough (hi Pokemon Stadium !) because games could write anything * in this field : most ucode_boot discard the value and just use 0xf7f anyway. * * Using ucode_boot_size should be more robust in this regard. **/ static bool is_task(struct hle_t* hle) { return (*dmem_u32(hle, TASK_UCODE_BOOT_SIZE) <= 0x1000); }
static void dump_task(struct hle_t* hle, const char *const filename) { FILE *f; f = fopen(filename, "r"); if (f == NULL) { f = fopen(filename, "w"); fprintf(f, "type = %d\n" "flags = %d\n" "ucode_boot = %#08x size = %#x\n" "ucode = %#08x size = %#x\n" "ucode_data = %#08x size = %#x\n" "dram_stack = %#08x size = %#x\n" "output_buff = %#08x *size = %#x\n" "data = %#08x size = %#x\n" "yield_data = %#08x size = %#x\n", *dmem_u32(hle, TASK_TYPE), *dmem_u32(hle, TASK_FLAGS), *dmem_u32(hle, TASK_UCODE_BOOT), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE), *dmem_u32(hle, TASK_UCODE), *dmem_u32(hle, TASK_UCODE_SIZE), *dmem_u32(hle, TASK_UCODE_DATA), *dmem_u32(hle, TASK_UCODE_DATA_SIZE), *dmem_u32(hle, TASK_DRAM_STACK), *dmem_u32(hle, TASK_DRAM_STACK_SIZE), *dmem_u32(hle, TASK_OUTPUT_BUFF), *dmem_u32(hle, TASK_OUTPUT_BUFF_SIZE), *dmem_u32(hle, TASK_DATA_PTR), *dmem_u32(hle, TASK_DATA_SIZE), *dmem_u32(hle, TASK_YIELD_DATA_PTR), *dmem_u32(hle, TASK_YIELD_DATA_SIZE)); fclose(f); } else fclose(f); }
static bool try_fast_audio_dispatching(struct hle_t* hle) { /* identify audio ucode by using the content of ucode_data */ uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA); uint32_t v; if (*dram_u32(hle, ucode_data) == 0x00000001) { if (*dram_u32(hle, ucode_data + 0x30) == 0xf0000f00) { v = *dram_u32(hle, ucode_data + 0x28); switch(v) { case 0x1e24138c: /* audio ABI (most common) */ alist_process_audio(hle); return true; case 0x1dc8138c: /* GoldenEye */ alist_process_audio_ge(hle); return true; case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */ alist_process_audio_bc(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v); } } else { v = *dram_u32(hle, ucode_data + 0x10); switch(v) { case 0x11181350: /* MarioKart, WaveRace (E) */ alist_process_nead_mk(hle); return true; case 0x111812e0: /* StarFox (J) */ alist_process_nead_sfj(hle); return true; case 0x110412ac: /* WaveRace (J RevB) */ alist_process_nead_wrjb(hle); return true; case 0x110412cc: /* StarFox/LylatWars (except J) */ alist_process_nead_sf(hle); return true; case 0x1cd01250: /* FZeroX */ alist_process_nead_fz(hle); return true; case 0x1f08122c: /* YoshisStory */ alist_process_nead_ys(hle); return true; case 0x1f38122c: /* 1080° Snowboarding */ alist_process_nead_1080(hle); return true; case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */ alist_process_nead_oot(hle); return true; case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */ alist_process_nead_mm(hle); return true; case 0x109411f8: /* Zelda MM (E Beta) */ alist_process_nead_mmb(hle); return true; case 0x1eac11b8: /* AnimalCrossing */ alist_process_nead_ac(hle); return true; case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */ musyx_v2_task(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v); } } } else { v = *dram_u32(hle, ucode_data + 0x10); switch(v) { case 0x00000001: /* MusyX v1 RogueSquadron, ResidentEvil2, PolarisSnoCross, TheWorldIsNotEnough, RugratsInParis, NBAShowTime, HydroThunder, Tarzan, GauntletLegend, Rush2049 */ musyx_v1_task(hle); return true; case 0x0000127c: /* naudio (many games) */ alist_process_naudio(hle); return true; case 0x00001280: /* BanjoKazooie */ alist_process_naudio_bk(hle); return true; case 0x1c58126c: /* DonkeyKong */ alist_process_naudio_dk(hle); return true; case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */ alist_process_naudio_mp3(hle); return true; case 0x1ab0140c: /* ConkerBadFurDay */ alist_process_naudio_cbfd(hle); return true; default: HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v); } } return false; }
/** * Try to figure if the RSP was launched using osSpTask* functions * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless). * * Previously, the ucode_size field was used to determine this, * but it is not robust enough (hi Pokemon Stadium !) because games could write anything * in this field : most ucode_boot discard the value and just use 0xf7f anyway. * * Using ucode_boot_size should be more robust in this regard. **/ static int is_task(void) { return (*dmem_u32(TASK_UCODE_BOOT_SIZE) <= 0x1000); }
void dmem_store_u32(const uint32_t* src, uint16_t address, size_t count) { /* Optimization for uint32_t */ memcpy(dmem_u32(address), src, count * sizeof(uint32_t)); }
void dmem_load_u32(uint32_t* dst, uint16_t address, size_t count) { /* Optimization for uint32_t */ memcpy(dst, dmem_u32(address), count * sizeof(uint32_t)); }