Пример #1
0
        public MIPSEvaluator(ROMHandler.ROMHandler rom, ROMHandler.DMATableEntry dma, uint ramadr, RegisterHookDelegate reghook = null, ushort var = 0)
        {
            BaseAddress = ramadr;

            Registers = new uint[32];
            Stack     = new uint[256 * MIPS.SafetyVal];
            StackPos  = (int)(128 * MIPS.SafetyVal);

            Sections = new OvlSections(rom, dma, 0);

            MemoryMap = new List <MemoryRegion>();
            MemoryMap.Add(new MemoryRegion(Sections.text, ramadr + Sections.textVA));
            MemoryMap.Add(new MemoryRegion(Sections.data, ramadr + Sections.dataVA));
            MemoryMap.Add(new MemoryRegion(Sections.rodata, ramadr + Sections.rodataVA));
            MemoryMap.Add(new MemoryRegion(Sections.bss, ramadr + Sections.bssVA));

            RegisterHook = reghook;

            SpecialOps = new List <SpecialOp>();
            SpecialOps.Add(new SpecialOp(MIPS.LH((uint)MIPS.Register.R0, 0x1C, (uint)MIPS.Register.A0), MIPS.LH((uint)MIPS.Register.R0, 0x1C, (uint)MIPS.Register.A0), var));
            SpecialOps.Add(new SpecialOp(MIPS.LH((uint)MIPS.Register.R0, 0x1C, (uint)MIPS.Register.S0), MIPS.LH((uint)MIPS.Register.R0, 0x1C, (uint)MIPS.Register.A0), var));

            Watches = new List <uint>();
        }
Пример #2
0
        private void Evaluate(byte[] words, int pos)
        {
            uint word = Endian.SwapUInt32(BitConverter.ToUInt32(words, pos));
            uint imm = 0, calcadr = 0, target = 0;

            foreach (SpecialOp sop in SpecialOps)
            {
                if ((word & sop.Mask) == sop.Opcode)
                {
                    if ((word & 0xFC000000) == 0)
                    {
                        Registers[MIPS.GetRD(word)] = sop.Value;
                    }
                    else
                    {
                        Registers[MIPS.GetRT(word)] = sop.Value;
                    }
                    return;
                }
            }

            switch ((MIPS.Opcode)((word >> 26) & 0x3F))
            {
            case MIPS.Opcode.JAL:
                target = MIPS.GetTARGET(word);
                Evaluate(words, pos + 4);
                ReportResult(target, pos);
                Array.Clear(Registers, 1, 15);
                Array.Clear(Registers, 24, 4);

                Registers[(int)MIPS.Register.RA] = (BaseAddress & 0xFFFFFF) + (uint)(pos + 4);

                foreach (MemoryRegion mem in MemoryMap)
                {
                    if (target > (mem.Address & 0xFFFFFF) && mem.Data.Length + (mem.Address & 0xFFFFFF) > target)
                    {
                        pos = (int)(target - (BaseAddress & 0xFFFFFF));
                        break;
                    }
                }
                break;

            case MIPS.Opcode.SLLV:
                Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] << (int)MIPS.GetRS(word);
                break;

            case MIPS.Opcode.ADDIU:
                imm = MIPS.GetIMM(word);
                if ((imm & 0x8000) != 0)
                {
                    imm |= 0xFFFF0000;
                }
                Registers[MIPS.GetRT(word)] = Registers[MIPS.GetRS(word)] + imm;
                if (MIPS.GetRT(word) == MIPS.GetRS(word) && MIPS.GetRT(word) == (uint)MIPS.Register.SP)
                {
                    StackPos += (short)imm;
                }
                break;

            case MIPS.Opcode.LUI:
                Registers[MIPS.GetRT(word)] = MIPS.GetIMM(word) << 16;
                break;

            case MIPS.Opcode.ANDI:
                Registers[MIPS.GetRT(word)] = Registers[MIPS.GetRS(word)] & MIPS.GetIMM(word);
                break;

            case MIPS.Opcode.ORI:
                Registers[MIPS.GetRT(word)] = Registers[MIPS.GetRS(word)] | MIPS.GetIMM(word);
                break;

            case MIPS.Opcode.SW:
                if (MIPS.GetRS(word) == (uint)MIPS.Register.SP)
                {
                    Stack[StackPos + MIPS.GetIMM(word)] = Registers[MIPS.GetRT(word)];
                }
                break;

            /*
             * case MIPS.Opcode.LH:
             * imm = MIPS.GetIMM(word);
             * calcadr = imm + Registers[MIPS.GetRS(word)];
             *
             * if (MIPS.GetRS(word) == (uint)MIPS.Register.SP)
             * {
             *  Registers[MIPS.GetRT(word)] = Stack[StackPos + imm];
             *  break;
             * }
             *
             * foreach (MemoryRegion mem in MemoryMap)
             * {
             *  if (calcadr > mem.Address && mem.Data.Length + mem.Address > calcadr)
             *  {
             *      Registers[MIPS.GetRT(word)] = (uint)Endian.SwapInt16(BitConverter.ToInt16(mem.Data, (int)(calcadr - mem.Address)));
             *      break;
             *  }
             * }
             * break;
             */
            case MIPS.Opcode.LW:
                imm = MIPS.GetIMM(word);
                if ((imm & 0x8000) != 0)
                {
                    imm |= 0xFFFF0000;
                }
                calcadr = imm + Registers[MIPS.GetRS(word)];

                if (MIPS.GetRS(word) == (uint)MIPS.Register.SP)
                {
                    Registers[MIPS.GetRT(word)] = Stack[StackPos + imm];
                    break;
                }

                foreach (MemoryRegion mem in MemoryMap)
                {
                    if (calcadr > mem.Address && mem.Data.Length + mem.Address > calcadr)
                    {
                        Registers[MIPS.GetRT(word)] = Endian.SwapUInt32(BitConverter.ToUInt32(mem.Data, (int)(calcadr - mem.Address)));
                        break;
                    }
                }
                break;

            /*
             * case MIPS.Opcode.LHU:
             * imm = MIPS.GetIMM(word);
             * if ((imm & 0x8000) != 0) imm |= 0xFFFF0000; //????
             * calcadr = imm + Registers[MIPS.GetRS(word)];
             *
             * if (MIPS.GetRS(word) == (uint)MIPS.Register.SP)
             * {
             *  Registers[MIPS.GetRT(word)] = Stack[StackPos + imm];
             *  break;
             * }
             *
             * foreach (MemoryRegion mem in MemoryMap)
             * {
             *  if (calcadr > mem.Address && mem.Data.Length + mem.Address > calcadr)
             *  {
             *      Registers[MIPS.GetRT(word)] = Endian.SwapUInt16(BitConverter.ToUInt16(mem.Data, (int)(calcadr - mem.Address)));
             *      break;
             *  }
             * }
             * break;
             */
            case MIPS.Opcode.TYPE_R:
            {
                switch ((MIPS.Opcode_R)(word & 0x3F))
                {
                case MIPS.Opcode_R.SLL:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] << (int)MIPS.GetSA(word);
                    break;

                case MIPS.Opcode_R.SRA:
                case MIPS.Opcode_R.SRL:             /*test!*/
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] >> (int)MIPS.GetSA(word);
                    break;

                case MIPS.Opcode_R.ADDU:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] + Registers[MIPS.GetRS(word)];
                    break;

                case MIPS.Opcode_R.SUBU:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] - Registers[MIPS.GetRS(word)];
                    break;

                case MIPS.Opcode_R.AND:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] & Registers[MIPS.GetRS(word)];
                    break;

                case MIPS.Opcode_R.OR:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] | Registers[MIPS.GetRS(word)];
                    break;

                case MIPS.Opcode_R.XOR:
                    Registers[MIPS.GetRD(word)] = Registers[MIPS.GetRT(word)] ^ Registers[MIPS.GetRS(word)];
                    break;

                case MIPS.Opcode_R.JR:
                    if (MIPS.GetRS(word) == (uint)MIPS.Register.RA)
                    {
                        Array.Clear(Registers, 1, 15);
                        Array.Clear(Registers, 24, 4);
                        pos = (int)Registers[(int)MIPS.Register.RA];
                    }
                    break;

                default:
                    break;
                }
            }
            break;

            default:
                break;
            }

            if (RegisterHook != null)
            {
                RegisterHook(Registers);
            }
        }