示例#1
0
 /******************************************************
  * CALL: reset();
  * TASK: Sets the member variables to their initiated value.
  *****************************************************/
 public void reset()
 {
     _output          = new Bit12(0);
     _instructionPtr  = 0;
     _workingRegister = new Bit12(0);
     resetMemory();
 }
示例#2
0
        /******************************************************
         * CALL: bool ok = addrIdxToUpdate(Bit12, out byte);
         * TASK: Handles indexing of STORE, CALL and RETURN
         *     instructions.
         *****************************************************/
        public bool addrIdxToUpdate(Bit12 command, out byte idx)
        {
            byte       val = (byte)extractVal(command.value());
            Operations opr = Operations.LOAD;

            if (!extractOperation(command.value(), out opr))
            {
                idx = 0;
                return(false);
            }

            switch (opr)
            {
            case Operations.STORE: {
                idx = (byte)(val);
                return(true);
            }

            case Operations.CALL: {
                idx = (byte)(255 - _memoryStack.size());
                return(true);
            }

            case Operations.RETURN: {
                idx = (byte)(255 - _memoryStack.size() - 1);
                return(true);
            }

            default: {
                idx = 0;
                return(false);
            }
            }
        }
示例#3
0
        /******************************************************
         * CALL: bool ok = stringToMachine(string, out Bit12);
         * TASK: Converts the string to machine code and returns
         *     true if doing so successfully.
         *****************************************************/
        public bool stringToMachine(string str, out Bit12 machineCode)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                machineCode = new Bit12(0);
                return(true);
            }

            bool binary = isBinary(str);

            if (binary && str.Length == 12)
            {
                machineCode = new Bit12(Convert.ToInt16(str, 2));
                return(true);
            }
            else
            {
                if (!assemblyToMachine(str, out machineCode))
                {
                    machineCode = new Bit12(0);
                    return(false);
                }

                return(true);
            }
        }
示例#4
0
        /******************************************************
         * CALL: Clicking the step back button.
         * TASK: Rolls back the program one step i.e. undo the
         *     previous operation.
         *****************************************************/
        private void Button_StepBack_Click(object sender, RoutedEventArgs e)
        {
            if (_runTimer.IsEnabled)
            {
                errorCode("Cannot undo while running the application.");
                return;
            }

            if (_assemblerModel.undoStack().size() == 0)
            {
                errorCode("Nothing to undo.");
                return;
            }

            if (_assemblerModel.undoStack().size() == 1)
            {
                Keyboard.ClearFocus();
                _currentTextBox.Foreground = (Brush)FindResource("TextBoxForegroundOff");
                clearUserMsg();
                _currentTextBox.IsReadOnly = false;
                showButtonAsEnabled(ButtonType.Stop);
            }

            UndoStorage undoValues  = _assemblerModel.undo();
            Bit12       currentAddr = _assemblerModel.getAddr(_assemblerModel.instructionPtr());
            Operations  opr         = Operations.LOAD;

            _assemblerModel.extractOperation(currentAddr.value(), out opr);

            // Mark current row
            markRow(getMMRowOfPosition(255 - _assemblerModel.instructionPtr()));

            // Update graphics of changed memory
            byte index;

            if (_assemblerModel.addrIdxToUpdate(currentAddr, out index))
            {
                if (opr == Operations.RETURN)
                {
                    index += 2;
                }

                MemoryRow row = getMMRowOfPosition(255 - index);
                row.ShowMemoryAdress(_assemblerModel.getAddr(index));

                if (index > 250)
                {
                    MemoryRow stackRow = getStackRowOfPosition(255 - index);
                    stackRow.ShowMemoryAdress(_assemblerModel.getAddr(index));
                }
            }

            ValueRow_WorkingRegister.ShowMemoryAdress(_assemblerModel.workingRegister());
            ValueRow_Output.ShowMemoryAdress(_assemblerModel.output());

            lightIfOutputIsOn();

            ValueRow_InstructionPointer.ShowMemoryAdress(new Bit12(_assemblerModel.instructionPtr()));
        }
示例#5
0
        /******************************************************
         * CALL: programTick();
         * TASK: Progresses the execution of the program
         *     one instruction.
         *****************************************************/
        private void programTick()
        {
            Bit12      currentAddr = _assemblerModel.getAddr(_assemblerModel.instructionPtr());
            Operations opr;
            byte       val = (byte)_assemblerModel.extractVal(currentAddr.value());

            _assemblerModel.extractOperation(currentAddr.value(), out opr);

            if (opr == Operations.RETURN && _assemblerModel.stack().size() == 0)
            {
                errorCode("Attempted Return on an empty stack.");
                pauseProgram();
                return;
            }

            if (!_assemblerModel.processCurrentAddr())
            {
                errorCode("Invalid operation.");
                pauseProgram();
                return;
            }

            // Mark current row
            markRow(getMMRowOfPosition(255 - _assemblerModel.instructionPtr()));

            // Update graphics of changed memory
            byte index;

            if (_assemblerModel.addrIdxToUpdate(currentAddr, out index))
            {
                if (opr != Operations.STORE)
                {
                    index++;
                }

                MemoryRow row = getMMRowOfPosition(255 - index);
                row.ShowMemoryAdress(_assemblerModel.getAddr(index));

                if (index > 250)
                {
                    MemoryRow stackRow = getStackRowOfPosition(255 - index);
                    stackRow.ShowMemoryAdress(_assemblerModel.getAddr(index));
                }
            }

            ValueRow_WorkingRegister.ShowMemoryAdress(_assemblerModel.workingRegister());
            ValueRow_Output.ShowMemoryAdress(_assemblerModel.output());
            ValueRow_InstructionPointer.ShowMemoryAdress(new Bit12(_assemblerModel.instructionPtr()));

            //First bit on output sets the light
            lightIfOutputIsOn();
        }
示例#6
0
        /******************************************************
         * CALL: resetMemory();
         * TASK: Resets the memory.
         *****************************************************/
        public void resetMemory()
        {
            for (int i = 0; i < _size; i++)
            {
                _memory[i] = new Bit12(0);
            }

            while (_memoryStack.size() > 0)
            {
                _memoryStack.pop();
            }

            while (_undoStack.size() > 0)
            {
                _undoStack.pop();
            }
        }
示例#7
0
 public UndoStorage(Bit12[] memory
                    , MyStack <Bit12> memoryStack
                    , byte instructionPtr
                    , Bit12 workingRegister
                    , Bit12 input
                    , Bit12 output)
 {
     _memory      = new Bit12[memory.Length];
     _memoryStack = new MyStack <Bit12>(_memory);
     Array.Copy(memory, _memory, memory.Length);
     for (int i = 0; i < memoryStack.size(); i++)
     {
         _memoryStack.push(_memory[255 - i]);
     }
     _instructionPtr  = instructionPtr;
     _workingRegister = workingRegister;
     _output          = output;
 }
示例#8
0
        public AssemblerModel()
        {
            _size   = 256; // Leave this at 256 (many of our attributes are 8 bit)
            _memory = new Bit12[_size];
            for (int i = 0; i < _size; i++)
            {
                _memory[i] = new Bit12(0);
            }
            _memoryStack     = new MyStack <Bit12>(_memory);
            _undoStack       = new CircularStack <UndoStorage>(1000);
            _instructionPtr  = 0;
            _workingRegister = new Bit12(0);
            _input           = new Bit12(0);
            _output          = new Bit12(0);
            _labels          = new Dictionary <string, byte>();

            resetMemory();
        }
示例#9
0
        /******************************************************
         * CALL: bool ok = binaryStringToMachine(string, out Bit12);
         * TASK: Returns true if the parameter string was converted
         *     to Bit12 machine code successfully.
         *****************************************************/
        public bool binaryStringToMachine(string str, out Bit12 machineCode)
        {
            if (string.IsNullOrWhiteSpace(str))
            {
                machineCode = new Bit12(0);
                return(true);
            }

            bool binary = isBinary(str);

            if (!binary || str.Length != 12)
            {
                machineCode = new Bit12(0);
                return(false);
            }

            machineCode = new Bit12(Convert.ToInt16(str, 2));
            return(true);
        }
示例#10
0
        /******************************************************
         * CALL: updateGUIMemory(byte, byte, TextBox);
         * TASK: Updates the graphics of the different parts
         *     of the memory.
         *****************************************************/
        private void updateGUIMemory(byte from, byte to, TextBox textBox)
        {
            for (int i = from; i <= to; i++)
            {
                string str = "";
                if (i < textBox.LineCount)
                {
                    str = textBox.GetLineText(i);
                }

                char[] trimChars = new char[3] {
                    '\r', '\n', ' '
                };
                str = str.TrimEnd(trimChars);

                Bit12 val = new Bit12(0);
                if (!string.IsNullOrWhiteSpace(str))
                {
                    if (textBox == TextBox_Assembler)
                    {
                        _assemblerModel.assemblyToMachine(str, out val);
                    }
                    else
                    {
                        if (_assemblerModel.checkSyntaxMachine(str))
                        {
                            short tempval = Convert.ToInt16(str, 2);
                            val = new Bit12(tempval);
                        }
                    }
                }

                if (i > 250)
                {
                    MemoryRow stackRow = getStackRowOfPosition(255 - i);
                    stackRow.ShowMemoryAdress(val);
                }

                MemoryRow rad = getMMRowOfPosition(255 - i);
                rad.ShowMemoryAdress(val);
            }
        }
示例#11
0
        /******************************************************
         * CALL: ShowMemoryAdress();
         * TASK: Prints a row of ones and zeros in the memory.
         *****************************************************/
        public void ShowMemoryAdress(Bit12 val)
        {
            UniformGrid memoryGrid = this.BinaryMemoryAdress as UniformGrid;

            string str = Convert.ToString(val.value(), 2).PadLeft(12, '0');

            if (str.Length > 12)
            {
                str = str.Substring(str.Length - 12);
            }

            for (int i = 0; i < str.Length && i < memoryGrid.Children.Count; i++)
            {
                Label lab = memoryGrid.Children[i] as Label;
                if (str[i] == '0' || str[i] == '1')
                {
                    lab.Content = str[i];
                }
            }
        }
示例#12
0
        /******************************************************
         * CALL: bool ok = checkSyntaxAssemblyTextBox(TextBox);
         * TASK: Checks if any line entered in the assembler
         *     section contains unapproved characters.
         *****************************************************/
        private bool checkSyntaxAssemblyTextBox(TextBox textBox)
        {
            bool ok = true;

            for (int i = 0; i < textBox.LineCount; i++)
            {
                char[] trimChars = new char[3] {
                    '\r', '\n', ' '
                };
                string str = textBox.GetLineText(i).TrimEnd(trimChars);

                Bit12 val = new Bit12(0);
                if (!_assemblerModel.assemblyToMachine(str, out val))
                {
                    errorCode("Syntax error, row " + i + ": " + "\"" + str + "\"");
                    ok = false;
                }
            }

            return(ok);
        }
示例#13
0
        /******************************************************
         * CALL: bool ok = machineToAssembly(Bit12, out string);
         * TASK: Returns true if conversion from machine code
         *     to assembly code was done successfully.
         * NOTE: Returns false if the inputted Bit12 doesn't
         *     contain any (or unapproved) assembly instruction.
         *****************************************************/
        public bool machineToAssembly(Bit12 bits, out string assemblyCode)
        {
            Operations opr;

            if (!extractOperation(bits.value(), out opr))
            {
                assemblyCode = "";
                return(false);
            }
            assemblyCode = opr.ToString();

            // Special case
            if (assemblyCode == "IN" || assemblyCode == "OUT" || assemblyCode == "RETURN")
            {
                return(true);
            }

            // Otherwise read the value aswell
            byte addr = extractVal(bits.value());

            assemblyCode += " " + addr;
            return(true);
        }
示例#14
0
        /******************************************************
         * CALL: bool ok = textToModel(TextBox);
         * TASK: Inserts the input in the textbox to the memory.
         *****************************************************/
        private bool textToModel(TextBox textBox)
        {
            storeLabels();

            if (!checkSyntaxActiveTextbox())
            {
                return(false);
            }

            for (int i = 0; i < textBox.LineCount; i++)
            {
                char[] trimChars = new char[3] {
                    '\r', '\n', ' '
                };
                string str  = textBox.GetLineText(i).TrimEnd(trimChars);
                Bit12  bits = new Bit12(0);

                bool success = _assemblerModel.stringToMachine(str, out bits);
                Debug.Assert(success);

                _assemblerModel.setAddr((byte)i, bits);
            }
            return(true);
        }
示例#15
0
 /******************************************************
  * CALL: setAddr(byte, Bit12);
  * TASK: Sets position "byte" in memory to value "Bit12".
  *****************************************************/
 public void setAddr(byte idx, Bit12 val)
 {
     Debug.Assert(idx >= 0 && idx < _size);
     _memory[idx] = val;
 }
示例#16
0
 /******************************************************
  * CALL: setOutput(Bit12);
  * TASK: Sets the _output property to the parameter Bit12.
  *****************************************************/
 public void setOutput(Bit12 output)
 {
     _output = output;
 }
示例#17
0
 /******************************************************
  * CALL: setInput(Bit12);
  * TASK: Sets input.
  *****************************************************/
 public void setInput(Bit12 input)
 {
     _input = input;
 }
示例#18
0
        /******************************************************
         * CALL: processCurrentAddr();
         * TASK: Interprets the current address and runs the
         *     corresponding function.
         *****************************************************/
        public bool processCurrentAddr()
        {
            Bit12      current = _memory[_instructionPtr];
            Operations opr     = Operations.LOAD;
            byte       addr    = (byte)extractVal(current.value());

            if (!extractOperation(current.value(), out opr))
            {
                return(false);
            }

            _undoStack.push(new UndoStorage(_memory, _memoryStack, _instructionPtr, _workingRegister, _input, _output));


            switch (opr)
            {
            case Operations.LOAD: {
                _workingRegister = _memory[addr];
                _instructionPtr  = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.STORE: {
                _memory[addr]   = _workingRegister;
                _instructionPtr = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.ADD: {
                _workingRegister += _memory[addr];
                _instructionPtr   = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.SUB: {
                _workingRegister -= _memory[addr];
                _instructionPtr   = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.MUL: {
                _workingRegister *= _memory[addr];
                _instructionPtr   = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.JUMP: {
                _instructionPtr = addr;
            } break;

            case Operations.PJUMP: {
                if (_workingRegister > new Bit12(0))
                {
                    _instructionPtr = addr;
                }
                else
                {
                    _instructionPtr++;
                }
            } break;

            case Operations.IN: {
                _workingRegister = _input;
                _instructionPtr  = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.OUT: {
                _output         = _workingRegister;
                _instructionPtr = (byte)(++_instructionPtr % _size);
            } break;

            case Operations.CALL: {
                _instructionPtr++;
                _memoryStack.push(new Bit12(_instructionPtr));
                _instructionPtr = addr;
            } break;

            case Operations.RETURN: {
                _instructionPtr = (byte)_memoryStack.top().value();
                _memoryStack.pop();
            } break;
            }

            return(true);
        }
示例#19
0
        /******************************************************
         * CALL: bool ok = assemblyToMachine(string, out Bit12);
         * TASK: Converts the inputted assembly string to Bit12
         *     machine code.
         *****************************************************/
        public bool assemblyToMachine(string assemblyString, out Bit12 machineCode)
        {
            if (isBinary(assemblyString) && assemblyString.Length == 12)
            {
                machineCode = new Bit12(0);
                return(false);
            }


            string label = "";

            if (containsLabel(assemblyString, out label) == LabelStatus.Success)
            {
                label          = ":" + label;
                assemblyString = assemblyString.Replace(label, "");
                if (assemblyString.Length != 0)
                {
                    assemblyString = assemblyString.TrimStart(' ');
                }
            }

            // Empty lines to create space are fine
            if (assemblyString == "\r\n" || assemblyString == "\r" || assemblyString == "\n" || string.IsNullOrWhiteSpace(assemblyString))
            {
                machineCode = new Bit12(0);
                return(true);
            }

            char[] trimChars = new char[3] {
                '\r', '\n', ' '
            };
            assemblyString = assemblyString.TrimEnd(trimChars);

            string[] splitString = assemblyString.Split(' ');

            // Special case where length is 1 and is a constant(number)
            if (splitString.Length == 1)
            {
                short val = 0;
                if (short.TryParse(splitString[0], out val))
                {
                    if (val < -2048 || val > 2047)
                    {
                        machineCode = new Bit12(0);
                        return(false);
                    }
                    machineCode = new Bit12(val);
                    return(true);
                }
            }

            Operations opr  = Operations.LOAD;
            byte       addr = 0;

            label = "";
            if (splitString.Length == 2 &&
                Enum.TryParse(splitString[0], false, out opr) &&
                (byte.TryParse(splitString[1], out addr) || referencesLabel(assemblyString, out label)) &&
                !(splitString[0] == "IN" || splitString[0] == "OUT" || splitString[0] == "RETURN"))
            {
                if (label.Length > 0)
                {
                    addr = _labels[label];
                }

                machineCode  = new Bit12((short)opr);
                machineCode  = new Bit12((short)(machineCode.value() << Constants.StartOprBit));
                machineCode += new Bit12(addr);

                return(true);
            }

            if (splitString.Length == 1 &&
                (splitString[0] == "IN" || splitString[0] == "OUT" || splitString[0] == "RETURN") &&
                Enum.TryParse(splitString[0], false, out opr))
            {
                machineCode = new Bit12((short)((short)opr << Constants.StartOprBit));
                return(true);
            }

            machineCode = new Bit12(0);
            return(false);
        }
示例#20
0
        /******************************************************
         * CALL: bool ok = SelfTest();
         * TASK: Used at debugging. The method calls every (testable)
         *    method in the class and returns true if no bug could
         *    be found.
         *****************************************************/
        public bool SelfTest()
        {
            bool ok = false;

            ok = (_size == _memory.GetLength(0));

            if (!ok)
            {
                Debug.Write("SelfTest failed in GUIProjekt.AssemblerModel: size of _memory was "
                            + _memory.GetLength(0)
                            + ", expected " + _size + "\n");
            }


            ok = ok && 255 == createMask(0, 7) &&
                 63 == createMask(0, 5) &&
                 2032 == createMask(4, 10) &&
                 3840 == createMask(8, 11) &&
                 4095 == createMask(0, 11) &&
                 1020 == createMask(2, 9);
            System.Diagnostics.Debug.WriteLine("createMask: " + ok);


            Operations opr;

            ok = ok && extractOperation(2800, out opr) &&
                 extractOperation(256, out opr) &&
                 extractOperation(0, out opr) &&
                 extractOperation(1, out opr) &&
                 extractOperation(1337, out opr);
            System.Diagnostics.Debug.WriteLine("extractOperation: " + ok);


            short bits1 = 400;
            short bits2 = 255;
            short bits3 = 600;
            short bits4 = 800;
            short bits5 = 1028;
            short bits6 = 2950;

            ok = ok && 1 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits1) &&
                 0 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits2) &&
                 2 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits3) &&
                 3 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits4) &&
                 4 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits5) &&
                 11 == (byte)extractValFromBits(Constants.StartOprBit, Constants.EndOprBit, bits6);
            System.Diagnostics.Debug.WriteLine("extractValFromBits: " + ok);


            string labelStr = "";

            ok = ok && LabelStatus.NoLabel == containsLabel("", out labelStr) &&
                 LabelStatus.NoLabel == containsLabel("MUL 420", out labelStr) &&
                 LabelStatus.SyntaxError == containsLabel(":", out labelStr) &&
                 LabelStatus.SyntaxError == containsLabel(":5", out labelStr) &&
                 LabelStatus.Blacklisted == containsLabel(":RETURN", out labelStr) &&
                 LabelStatus.Blacklisted == containsLabel(":ADD 60", out labelStr) &&
                 LabelStatus.Success == containsLabel(":HEJ 42", out labelStr) &&
                 LabelStatus.Success == containsLabel(":VARMT 255", out labelStr);
            System.Diagnostics.Debug.WriteLine("containsLabel: " + ok);


            ok = ok && isBinary("00000000") &&
                 isBinary("11111111") &&
                 isBinary("01010110") &&
                 isBinary("0") &&
                 isBinary("1");
            System.Diagnostics.Debug.WriteLine("isBinary: " + ok);


            Bit12 machineCode = new Bit12(0);

            ok = ok && stringToMachine("000100010001", out machineCode) &&
                 stringToMachine("101011101110", out machineCode) &&
                 stringToMachine("011011110000", out machineCode) &&
                 stringToMachine(" ", out machineCode);
            System.Diagnostics.Debug.WriteLine("stringToMachine: " + ok);


            ok = ok && binaryStringToMachine(" ", out machineCode) &&
                 binaryStringToMachine("011111111110", out machineCode) &&
                 binaryStringToMachine("100000000001", out machineCode);
            System.Diagnostics.Debug.WriteLine("binaryStringToMachine: " + ok);


            string assemCode = "";
            Bit12  val1      = new Bit12(1024);
            Bit12  val2      = new Bit12(2048);
            Bit12  val3      = new Bit12(2560);
            Bit12  val4      = new Bit12(1500);
            Bit12  val5      = new Bit12(666);
            Bit12  val6      = new Bit12(1);

            ok = ok && machineToAssembly(val1, out assemCode) &&
                 machineToAssembly(val2, out assemCode) &&
                 machineToAssembly(val3, out assemCode) &&
                 machineToAssembly(val4, out assemCode) &&
                 machineToAssembly(val5, out assemCode) &&
                 machineToAssembly(val6, out assemCode);
            System.Diagnostics.Debug.WriteLine("machineToAssembly: " + ok);


            Bit12 bit = new Bit12(0);

            ok = ok && assemblyToMachine(" ", out bit) &&
                 assemblyToMachine("\n", out bit) &&
                 assemblyToMachine(":VARMT 100", out bit) &&
                 assemblyToMachine("IN", out bit) &&
                 assemblyToMachine("OUT", out bit) &&
                 assemblyToMachine("PJUMP 200", out bit);
            System.Diagnostics.Debug.WriteLine("assemblyToMachine: " + ok);


            ok = ok && checkSyntaxMachine("000011111111") &&
                 checkSyntaxMachine("001101011111") &&
                 checkSyntaxMachine("100111111111") &&
                 checkSyntaxMachine("111100000000") &&
                 checkSyntaxMachine(" ") &&
                 checkSyntaxMachine("\n");
            System.Diagnostics.Debug.WriteLine("checkSyntaxMachine: " + ok);

            return(ok);
        }
示例#21
0
        public static Bit12 operator /(Bit12 a, Bit12 b)
        {
            Bit12 newBit12 = new Bit12((short)(a.value() / b.value()));

            return(newBit12);
        }