private ushort ReadControlRegister(ushort operand, RegControl index) { switch (index) { case RegControl.FL: return(FL); case RegControl.PC: return(PC); case RegControl.PS: if (PS_S) { return(m_PS); } Interrupt_UnPrivFault(operand); return(0); case RegControl.USP: return(USP); case RegControl.SSP: if (PS_S) { return(SSP); } return(USP); default: Interrupt_UndefFault(operand); return(0); } }
/// <summary> /// Executes an ALU operation. /// </summary> /// <param name="operand">Input: machine code word</param> /// <param name="value">Output: result value of operation</param> /// <param name="destination">Output: index of general register result should be written to.</param> private void BitPatternALU(ushort operand, out ushort value, out RegGeneral destination) { ushort address; // Decode the operand word's constituent bits. FEDC BA98 7654 3210 // SAAA rrrE OOOO ORRR int addressingMode = (operand & 0x7000) >> 12; RegGeneral source = (RegGeneral)((operand & 0x0E00) >> 9); bool eightBitMode = (operand & 0x0100) != 0; destination = (RegGeneral)(operand & 0x0007); // R = destination register SegmentIndex dataSeg = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS; switch (addressingMode) // will always be between 0x0 and 0x7 { case 0: // Addressing mode: Immediate (r == 0), Absolute (r == 1), else Control Register. if (source == 0) // Immediate { value = eightBitMode ? ReadMemInt8(PC, SegmentIndex.CS) : ReadMemInt16(PC, SegmentIndex.CS); PC += 2; // advance PC two bytes because we're reading an immediate value. } else if ((int)source == 1) // Absolute { address = ReadMemInt16(PC, SegmentIndex.CS); PC += 2; // advance PC two bytes because we're reading an immediate value. value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg); } else // Control Register { RegControl cr = (RegControl)((operand & 0x0700) >> 8); value = ReadControlRegister(operand, cr); } break; case 1: // Addressing mode: Register value = R[(int)source]; break; case 2: // Addressing mode: Indirect value = eightBitMode ? ReadMemInt8(R[(int)source], dataSeg) : ReadMemInt16(R[(int)source], dataSeg); break; case 3: // Addressing mode: Absolute Offset AKA Indirect Offset address = (ushort)(R[(int)source] + ReadMemInt16(PC, SegmentIndex.CS)); PC += 2; // advance PC two bytes because we're reading an immediate value. value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg); break; default: // addressing of 0x4 ~ 0x7 is an Indirect Indexed operation. int indexRegister = addressingMode; // bit pattern is 1ii, where ii = r4 - r7. address = (ushort)(R[(int)source] + R[indexRegister]); value = eightBitMode ? ReadMemInt8(address, dataSeg) : ReadMemInt16(address, dataSeg); break; } }
/// <summary> /// Executes a STOre operation (same bit pattern as ALU, but writes a value from r0 to destination). /// </summary> /// <param name="operand">Input: machine code word</param> /// <param name="destAddress">Output: memory address that is the destination of the operation</param> /// <param name="source">Output: general register that is the source of the operation</param> private void BitPatternSTO(ushort operand, out ushort destAddress, out RegGeneral source) { // Decode the operand word's constituent bits. FEDC BA98 7654 3210 // SAAA rrrE OOOO ORRR int addressingMode = (operand & 0x7000) >> 12; RegGeneral addrRegister = (RegGeneral)((operand & 0x0E00) >> 9); source = (RegGeneral)(operand & 0x0007); // R = source register switch (addressingMode) // will always be between 0x0 and 0x7 { case 0: // Immediate (r == 0), Absolute (r == 1), else Control Register if (addrRegister == 0) { // Immediate - no such addressing mode for STO. source = RegGeneral.None; destAddress = 0; Interrupt_UndefFault(operand); } else if ((int)addrRegister == 1) { destAddress = ReadMemInt16(PC, SegmentIndex.CS); PC += 2; // advance PC two bytes because we're reading an immediate value. } else { RegControl cr = (RegControl)((operand & 0x0700) >> 8); WriteControlRegister(operand, cr, R[(int)source]); // set source = none so calling function doesn't attempt to interpret this as well. source = RegGeneral.None; destAddress = 0; } break; case 1: // Register - no such addressing mode for STO. source = RegGeneral.None; destAddress = 0; Interrupt_UndefFault(operand); break; case 2: // Indirect destAddress = R[(int)addrRegister]; break; case 3: // Absolute Offset AKA Indirect Offset destAddress = (ushort)(R[(int)addrRegister] + ReadMemInt16(PC, SegmentIndex.CS)); PC += 2; // advance PC two bytes because we're reading an immediate value. break; default: // $8-$F are Indirect Indexed operations. int indexRegister = addressingMode; // bit pattern is 01ii, indicating r4 - r7. destAddress = (ushort)(R[(int)source] + R[indexRegister]); break; } }
private void LoadControls(string regsettings) { var properties = test.GetProperties(new MemberInfo()); string groupname = ""; Panel grpPanel = null; XDocument doc = XDocument.Load(regsettings); XElement root = doc.Root; foreach (XElement elem in root.Elements().OrderBy(e => e.Attribute("Group").Value)) { if (elem.Attribute("Group").Value != groupname) { if (grpPanel != null && grpPanel.Controls.Count > 0) { mControls.Controls.Add(grpPanel); } groupname = elem.Attribute("Group").Value; grpPanel = new Panel { ID = "pnl" + groupname, GroupingText = test.SplitCamelCase(groupname) }; } var prop = properties.SingleOrDefault(p => p.Name == elem.Name.LocalName); Registration pr = (Registration)prop.GetCustomAttributes(false)[0]; var isVisible = Convert.ToBoolean(elem.Attribute("Show").Value); var isRequired = Convert.ToBoolean(elem.Attribute("Require").Value); if (isVisible) { RegControl ctl = new RegControl() { LabelText = test.SplitCamelCase(elem.Name.LocalName), ControlID = elem.Name.LocalName, ControlType = pr.Control, InvalidMessage = isRequired ? elem.Name.LocalName + " Is required" : "", Show = true, Required = isRequired, ClientScript = "false", CssClass = isRequired ? "label_mandatory" : "label_not_mandatory" }; if (grpPanel != null) { grpPanel.Controls.Add(ctl); } } } if (grpPanel != null && grpPanel.Controls.Count > 0) { mControls.Controls.Add(grpPanel); } }
private void WriteControlRegister(ushort operand, RegControl index, ushort value) { switch (index) { case RegControl.FL: FL = value; break; case RegControl.PC: PC = value; break; case RegControl.PS: if (PS_S) { PS = value; } else { Interrupt_UnPrivFault(operand); } break; case RegControl.USP: USP = value; break; case RegControl.SSP: if (PS_S) { SSP = value; } else { USP = value; } break; default: Interrupt_UndefFault(operand); break; } }
private string NameOfRegSP(RegControl register) { switch (register) { case RegControl.FL: return("FL"); case RegControl.PC: return("PC"); case RegControl.PS: return("PS"); case RegControl.USP: return("USP"); case RegControl.SSP: return("SP"); default: return("??"); } }
private Panel LoadGroupControls(string groupname) { var properties = RegHelper.GetProperties(new MemberInfo()); Panel grpPanel = null; _memberFields = XDocument.Load(_regsettings); XElement root = _memberFields.Root; //get all the controls to be shown and order by groupname so we can arrange on the wizard grpPanel = new Panel { ID = "pnl" + groupname, GroupingText = RegHelper.SplitCamelCase(groupname) }; foreach (XElement elem in root.Elements().Where(a => a.Attribute("Show").Value == "true" && a.Attribute("Group").Value == groupname)) { //get the custom attributes for the current property so we can get the control to use var prop = properties.SingleOrDefault(p => p.Name == elem.Name.LocalName); Registration attr = (Registration)prop.GetCustomAttributes(false)[0]; //var isVisible = Convert.ToBoolean(elem.Attribute("Show").Value); var isRequired = Convert.ToBoolean(elem.Attribute("Require").Value); RegControl ctl = new RegControl() { ValidationGroup = CreateUserWizard1.ID, LabelText = RegHelper.SplitCamelCase(elem.Name.LocalName), ControlID = elem.Name.LocalName, ControlType = attr.Control, InvalidMessage = isRequired ? elem.Name.LocalName + " Is required" : "", Show = true, Required = isRequired, ClientScript = "true", CssClass = isRequired ? "label_mandatory" : "label_not_mandatory" }; //add the new control to the panel grpPanel.Controls.Add(ctl); } return grpPanel; }
private void WriteControlRegister(ushort operand, RegControl index, ushort value) { switch (index) { case RegControl.FL: FL = value; break; case RegControl.PC: PC = value; break; case RegControl.PS: if (PS_S) PS = value; else Interrupt_UnPrivFault(operand); break; case RegControl.USP: USP = value; break; case RegControl.SSP: if (PS_S) SSP = value; else USP = value; break; default: Interrupt_UndefFault(operand); break; } }
private ushort ReadControlRegister(ushort operand, RegControl index) { switch (index) { case RegControl.FL: return FL; case RegControl.PC: return PC; case RegControl.PS: if (PS_S) return m_PS; Interrupt_UnPrivFault(operand); return 0; case RegControl.USP: return USP; case RegControl.SSP: if (PS_S) return SSP; return USP; default: Interrupt_UndefFault(operand); return 0; } }
private string NameOfRegSP(RegControl register) { switch (register) { case RegControl.FL: return "FL"; case RegControl.PC: return "PC"; case RegControl.PS: return "PS"; case RegControl.USP: return "USP"; case RegControl.SSP: return "SP"; default: return "??"; } }
private string DisassembleALU(string name, ushort operand, ushort nextword, ushort address, bool showMemoryContents, out ushort instructionSize) { int addressingmode = (operand & 0x7000) >> 12; RegGeneral regDest = (RegGeneral)(operand & 0x0007); RegGeneral regSrc = (RegGeneral)((operand & 0x0E00) >> 9); bool isEightBit = (operand & 0x0100) != 0; SegmentIndex segData = (operand & 0x8000) != 0 ? SegmentIndex.ES : SegmentIndex.DS; switch (addressingmode) { case 0: if (regSrc == 0) // immediate { if (name == "STO") { instructionSize = 2; return("???"); } instructionSize = 4; string disasm = $"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, ${nextword:X4}"; if (showMemoryContents) { disasm = AppendMemoryContents(disasm, nextword); } return(disasm); } if ((int)regSrc == 1) // absolute { instructionSize = 4; string disasm = $"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [${nextword:X4}]"; if (showMemoryContents) { disasm = AppendMemoryContents(disasm, DebugReadMemory(nextword, segData)); } return(disasm); } else // control register { instructionSize = 2; RegControl cr = (RegControl)((operand & 0x0700) >> 8); string disasm = $"{name,-8}{NameOfRegGP(regDest)}, {NameOfRegSP(cr)}"; if (showMemoryContents) { disasm = AppendMemoryContents(disasm, nextword); } return(disasm); } case 1: // Register instructionSize = 2; return ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, {NameOfRegGP(regSrc),-12}(${R[(int)regSrc]:X4})"); case 2: // Indirect instructionSize = 2; return ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)}] (${DebugReadMemory(R[(int)regSrc], segData):X4})"); case 3: // Indirect Offset (also Absolute Offset) instructionSize = 4; return ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)},${nextword:X4}] (${DebugReadMemory((ushort)(R[(int)regSrc] + nextword), segData):X4})"); default: // $4 - $7 are Indirect Indexed instructionSize = 2; RegGeneral regIndex = (RegGeneral)((operand & 0x7000) >> 12); return ($"{name + (isEightBit ? ".8" : string.Empty),-8}{NameOfRegGP(regDest)}, [{NameOfRegGP(regSrc)},{NameOfRegGP(regIndex)}] (${DebugReadMemory((ushort)(R[(int)regSrc] + R[(int)regIndex]), segData):X4})"); } }