//-------------------------------------------------------------- // Purpose: Loads contents of sequential memory addresses starting at // instr.RN into registers specified in <instr> // Returns: nothing //-------------------------------------------------------------- public void LDMFD(LoadStoreMultiple instr, bool generateDisasm) { instr.disasm.instruction = "ldmfd"; uint count = 0; uint backup = instr.regList, mask = 0x00000001; ArrayList regList = new ArrayList(); // store addresses of registers to be stored ArrayList disasmList = new ArrayList(); if (!generateDisasm) { for (int i = 0; i < 17; i++, count += 4) { byte lsb = (byte)(backup & mask); if (lsb == 1) { regList.Add(count); } backup >>= 1; } uint RN = Computer.GetCPU().registers.ReadWord((uint)instr.RN * 4); uint address = RN; for (int i = 0; i < regList.Count; i++) { //if (!instr.U) address -= 4; uint data = Computer.GetCPU().progRAM.ReadWord(address); Computer.GetCPU().registers.WriteWord((uint)regList[i], data); address += 4; } if (instr.W) { Computer.GetCPU().registers.WriteWord((uint)instr.RN * 4, RN + ((uint)regList.Count * 4)); } } else { for (int i = 0; i < 17; i++, count += 4) { byte lsb = (byte)(backup & mask); if (lsb == 1) { disasmList.Add("r" + count / 4); } backup >>= 1; } instr.disasm.value = "r" + instr.RN.ToString() + (instr.W ? "" : "!") + ", {"; foreach (string s in disasmList) { instr.disasm.value += s + ", "; } instr.disasm.value = instr.disasm.value.Substring(0, instr.disasm.value.Length - 2) + "}"; } // read value at instr.RN into lowest register in instr.regList // continue reading values in sequential memory addresses into registers listed from least to greatest // read direction is specified by instr.U }
//-------------------------------------------------------------- // Purpose: Stores multiple registers into memory starting at address // in instr.RN // Returns: nothing //-------------------------------------------------------------- public void STMFD(LoadStoreMultiple instr, bool generateDisasm) { instr.disasm.instruction = "stmfd"; uint count = 0; uint backup = instr.regList, mask = 0x00000001; ArrayList regList = new ArrayList(); // store addresses of registers to be stored ArrayList disasmList = new ArrayList(); if (!generateDisasm) { for (int i = 0; i < 17; i++, count += 4) { byte lsb = (byte)(backup & mask); if (lsb == 1) { regList.Add(count); } backup >>= 1; } uint RN = Computer.GetCPU().registers.ReadWord((uint)instr.RN * 4); uint address = RN - ((uint)regList.Count * 4); for (int i = 0; i < regList.Count; i++) { //if (!instr.U) address -= 4; uint data = Computer.GetCPU().registers.ReadWord((uint)regList[i]); Computer.GetCPU().progRAM.WriteWord(address, data); address += 4; } if (instr.W) { Computer.GetCPU().registers.WriteWord((uint)instr.RN * 4, RN - ((uint)regList.Count * 4)); } } else { for (int i = 0; i < 17; i++, count += 4) { byte lsb = (byte)(backup & mask); if (lsb == 1) { disasmList.Add("r" + count / 4); } backup >>= 1; } instr.disasm.value = "r" + instr.RN.ToString() + (instr.W ? "" : "!") + ", {"; foreach (string s in disasmList) { instr.disasm.value += s + ", "; } instr.disasm.value = instr.disasm.value.Substring(0, instr.disasm.value.Length - 2) + "}"; } // store values in registers held in instr.regList to address in instr.RN // if instr.W is set, write the current PC value back into the PC }
public Instruction Create(uint data) { byte operationType = Instruction.GetOperationType(data); bool bit4 = Memory.TestFlagInData(data, 4); switch (operationType) { case 0x0: // 000 if (Memory.ExtractBits(data, 21, 24) == 0 && (Memory.ExtractBits(data, 4, 7) >> 4) == 0x09) // instruction is a MUL { Data dInstr = new Data(data); dInstr.DataMul(); dInstr.ExecuteInstruction(true); return(dInstr); } else if (bit4 == false) // Data Register, Immediate-shifted Register { Data dInstr = new Data(data); dInstr.DataRegImmShiftedReg(); dInstr.ExecuteInstruction(true); return(dInstr); } else if (bit4 == true && Memory.ExtractBits(data, 20, 24) >> 20 == 0x12) // BX instruction { Branch bInstr = new Branch(data); bInstr.Branch(); bInstr.ExecuteInstruction(true); return(bInstr); } else // Data Register-shifted Immediate { Data dInstr = new Data(data); dInstr.DataRegShiftedReg(); dInstr.ExecuteInstruction(true); return(dInstr); } case 0x1: // 001 - Data Immediate Data dataInstr = new Data(data); dataInstr.DataImmediate(); dataInstr.ExecuteInstruction(true); // generate disassembly return(dataInstr); case 0x2: // 010 - Load/Store Immediate LdStore ldstrInstr = new LdStore(data); ldstrInstr.LdStrImmediate(); ldstrInstr.ExecuteInstruction(true); return(ldstrInstr); case 0x3: // 011 - Load/Store Immediate-shifted Register LdStore ldstInstr = new LdStore(data); ldstInstr.LdStrImmShiftedReg(); ldstInstr.ExecuteInstruction(true); return(ldstInstr); case 0x4: // 100 - Load/Store Multiple LoadStoreMultiple ldstrMul = new LoadStoreMultiple(data); ldstrMul.LdStrMultiple(); ldstrMul.ExecuteInstruction(true); return(ldstrMul); case 0x5: // 101 - Branch Branch b = new Branch(data); b.Branch(); b.ExecuteInstruction(true); return(b); case 0x07: // 111 - SWI SWI swiInstr = new SWI(data); swiInstr.LoadDataSWI(); swiInstr.ExecuteInstruction(true); return(swiInstr); default: // an unsupported instruction was provided Instruction i = new Instruction(); return(i); } }