Пример #1
0
        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);
            }
        }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
        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);
        }