Beispiel #1
0
/**
 * 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;
}
Beispiel #4
0
/**
 * 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);
}
Beispiel #5
0
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));
}
Beispiel #6
0
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));
}