Exemple #1
0
        /// <summary>
        /// This method determines the next address, based on the current microinstruction,
        ///    status word, MRTN register, etc.
        /// </summary>
        public bool GetJump(MSmicrocodeStatement mc)
        { // TODO This hard code neglects the MScontrolTable!
            if (mc.jumpCode == 0)
            {
                // No jump; increment MPC and set to MUX register
                MicroRegisterContent[(int)RegisterSet.MUX] = ++MicroRegisterContent[(int)RegisterSet.MPC];
                return(true);
            }

            // TODO: rest of jump codes
            return(false);
        }
Exemple #2
0
        public bool PerformOneMicroStatement(MSmicrocodeStatement mc)
        {
            // handle the easy cases first. Note that increments do NOT affect the status
            if (ControlTable.aCTwrite[mc.write] == MSstate.RegSet.incPC_MAR)
            {
                PerformIncMAR(); PerformIncPC(); return(mseq.GetJump(mc));
            }

            if (ControlTable.aCTread[mc.read] == MSstate.RegSet.incPC)
            {
                PerformIncPC(); return(mseq.GetJump(mc));
            }

            if (ControlTable.aCTread[mc.read] == MSstate.RegSet.incMAR)
            {
                PerformIncMAR(); return(mseq.GetJump(mc));
            }

            // determine the source and destination of this instruction
            //    (Though they may not always be applicable)
            MSstate.RegSet RWdestination, RWsource;

            if (mc.write == 13 || mc.write == 15 || (mc.write > 0 && mc.write < 12))
            {
                RWdestination = ControlTable.aCTwrite[mc.write];
            }
            else
            {
                return(false); // TODO throw exception
            }
            if (mc.read == 13 || mc.read == 15 || (mc.read > 0 && mc.read < 10))
            {
                RWsource = ControlTable.aCTwrite[mc.read];
            }
            else
            {
                return(false); // TODO throw exception
            }
            // Handle the most frequent case (assignment), ALU "does" B
            if (ControlTable.aFn[mc.alu] == MScontrolTable.ALU_fn.B)
            {
                byte result = state.RegisterContent[RWsource];
                PerformAssign(RWdestination, result);
                return(SetStatusAndJump(result, mc));
            } // alu:B

            if (ControlTable.aFn[mc.alu] == MScontrolTable.ALU_fn.A)
            {
                byte result = state.RegisterContent[MSstate.RegSet.ALUin];
                PerformAssign(RWdestination, result);
                return(SetStatusAndJump(result, mc));
            } // alu:A

            if (ControlTable.aFn[mc.alu] == MScontrolTable.ALU_fn.not_A)
            {
                byte notA = (byte)~state.RegisterContent[MSstate.RegSet.ALUin];
                PerformAssign(RWdestination, notA);
                return(SetStatusAndJump(notA, mc));
            } // alu:not_A

            if (ControlTable.aFn[mc.alu] == MScontrolTable.ALU_fn.AandB)
            {
                byte A = state.RegisterContent[MSstate.RegSet.ALUin];
                byte B = state.RegisterContent[RWsource];
                // bitwise AND
                byte result = (byte)(A & B);
                PerformAssign(RWdestination, result);
                return(SetStatusAndJump(result, mc));
            } // alu:AandB

            if (ControlTable.aFn[mc.alu] == MScontrolTable.ALU_fn.AtB) // A plus B TODO: test
            {
                // All registers are stored as unsigned bytes. We need to use unsigned
                //    integers for the arithmetic operation
                uint A        = unchecked ((uint)state.RegisterContent[MSstate.RegSet.ALUin]);
                uint B        = unchecked ((uint)state.RegisterContent[RWsource]);
                uint uiResult = A + B;

                // adjust the result as necessary to fit into a byte
                bCarry = false;        // assume this until proven wrong
                byte byteResult = 0x0; // to receive the arithmetic result

                if (uiResult == 0)     // easy case
                {
                    byteResult = unchecked ((byte)uiResult);
                    bPos       = bNeg = false;
                    bZero      = true;
                }

                else if (uiResult < 128) // positive number, no carry
                {
                    byteResult = unchecked ((byte)uiResult);
                    bNeg       = bZero = false;
                    bPos       = true;
                }

                else if (uiResult < 256) // negative number, no carry
                {
                    byteResult = unchecked ((byte)uiResult);
                    bPos       = bZero = false;
                    bNeg       = true;
                }

                else // positive number with carry
                {
                    byteResult = unchecked ((byte)(uiResult % 256)); //truncate
                    bNeg       = bZero = false;
                    bPos       = bCarry = true;
                }

                PerformAssign(RWdestination, byteResult);
                return(mseq.GetJump(mc));
            } // alu:AandB

            // TODO: more ALU selections

            return(false);
        } // PerformOneMicroStatement
Exemple #3
0
 // This is called after an assignment or ALU operation.
 // result is the assigned or calculated value.
 // Note that bNOT_CDAV is controlled by events other than assignments
 //    and ALU operations.
 public bool SetStatusAndJump(byte result, MSmicrocodeStatement mc)
 {
     SetStatus(result);
     return(mseq.GetJump(mc));
 }