Esempio n. 1
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);
            }
            }
        }
Esempio n. 2
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();
        }
Esempio n. 3
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()));
        }
Esempio n. 4
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);
        }
Esempio n. 5
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];
                }
            }
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }