public static IEnumerable <string> DeepParse(BinaryReader memory, N64Ptr address) { bool keepParsing = true; MicrocodeParserTask task = new MicrocodeParserTask(address); memory.BaseStream.Position = address & 0xFFFFFF; while (keepParsing) { var microcode = new Microcode(memory); yield return($"{memory.BaseStream.Position - 8:X6}: {PrintMicrocode(memory, microcode, false)}"); keepParsing = TraceNext(memory, task, microcode); } }
/// <summary> /// Traces /// </summary> /// <param name="memory">Full RDRAM dump</param> /// <param name="address">The entry point address for the display list trace</param> /// <returns></returns> public static IEnumerable <(N64Ptr ptr, Microcode gbi, MicrocodeParserTask task)> DeepTrace(BinaryReader memory, N64Ptr address) { bool keepParsing = true; MicrocodeParserTask task = new MicrocodeParserTask(address); memory.BaseStream.Position = address & 0xFFFFFF; while (keepParsing) { var microcode = new Microcode(memory); var addr = memory.BaseStream.Position - 8; yield return(addr, microcode, task); keepParsing = TraceNext(memory, task, microcode); } }
private static bool TraceNext(BinaryReader br, MicrocodeParserTask task, Microcode microcode) { switch (microcode.Name) { case G_.G_MOVEWORD: if ((G_MW)((microcode.EncodingHigh >> 16) & 0xFF) == G_MW.G_MW_SEGMENT) { task.SegmentTable[(microcode.EncodingHigh & 0xFFFF) >> 2] = microcode.EncodingLow; } break; case G_.G_BRANCH_Z: { N64Ptr addr; var bank = (task.G_RDPHALF_1 >> 24) & 0xFF; if (bank < 16) { addr = task.SegmentTable[bank] + (task.G_RDPHALF_1 & 0xFFFFFF); } else { addr = task.G_RDPHALF_1; } //already advanced the cursor so this should be good task.DisplayListStack.Push(0x80000000 | br.BaseStream.Position); //jump br.BaseStream.Position = addr & 0xFFFFFF; } break; case G_.G_DL: { // set address we're branching to N64Ptr addr; var bank = (microcode.EncodingLow >> 24) & 0xFF; if (bank < 16) { addr = task.SegmentTable[bank] + (microcode.EncodingLow & 0xFFFFFF); } else { addr = microcode.EncodingLow; } //if branching if (((microcode.EncodingHigh >> 16) & 0xFF) == 0) { //already advanced the cursor so this should be good task.DisplayListStack.Push(0x80000000 | br.BaseStream.Position); } //jump br.BaseStream.Position = addr & 0xFFFFFF; } break; case G_.G_ENDDL: if (task.DisplayListStack.Count == 0) { return(false); } else { N64Ptr jumpback = task.DisplayListStack.Pop(); br.BaseStream.Position = jumpback & 0xFFFFFF; } break; case G_.G_RDPHALF_1: task.G_RDPHALF_1 = microcode.EncodingLow; break; case G_.G_RDPHALF_2: task.G_RDPHALF_2 = microcode.EncodingLow; break; } return(true); }