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>(); }
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); } }