Пример #1
0
        public Frame(Instruction instruction, int TState, IPort1 ip1, IPort2 ip2, PC pc, MAR mar, RAM ram,
                     List <string> ramContents, MDR mdr, IReg ireg, SEQ seq, string wbus_string,
                     AReg areg, ALU alu, Flag flagReg, TReg treg, BReg breg, CReg creg,
                     OReg3 oreg3, OReg4 oreg4, HexadecimalDisplay hexadecimalDisplay)
        {
            InstructionData = instruction;
            if (InstructionData.OpCode.Contains(','))
            {
                InstructionData.OpCode = InstructionData.OpCode.Replace(",", string.Empty);
            }

            this.TState = TState;

            this.AReg = areg.ToString_Frame_Use();
            this.BReg = breg.ToString_Frame_Use();
            this.CReg = creg.ToString_Frame_Use();
            this.TReg = treg.ToString_Frame_Use();
            this.IReg = ireg.ToString_Frame_Use();  // The real ToString() is in use with a substring in it.  This is needed for proper operation
            this.MAR  = mar.ToString_Frame_Use();
            this.MDR  = mdr.RegContent;

            this.PC   = pc.RegContent;
            this.ALU  = alu.ToString();
            this.WBus = wbus_string;

            this.OPort1             = oreg3.ToString_Frame_Use();
            this.OPort2             = oreg4.ToString_Frame_Use();
            this.HexadecimalDisplay = hexadecimalDisplay.RegContent;

            this.RAM = ramContents;

            this.SEQ     = seq.ToString();
            this.WBus    = wbus_string; // I didnt want to mess with the Singleton in the frame, so the value will just be passed as a string
            this.RAM_Reg = ram.ToString_Frame_Use();
            this.Flags   = flagReg.RegContent;

            if (instruction == null)
            {
                this.IReg = "???";
            }

            if (TState > 3)
            {
                Instruction = InstructionData.OpCode;
            }
            else
            {
                Instruction = "???";
            }
        }
Пример #2
0
        }                                             // The reason this is here is that the RAM might change if a STA simular command is issued.

        public Frame(string instruction, int TState, AReg areg, BReg breg, IReg ireg, MReg mreg, OReg oreg, PC pc, ALU alu, List <string> ramContents, RAM ram, SEQ seq, string wbus_string, Flags flags, IDecoder decoder, string SetName = "SAP1EMU")
        {
            this.RAM = new List <string>();

            this.TState = TState;

            this.AReg      = areg.ToString_Frame_Use();
            this.BReg      = breg.ToString_Frame_Use();
            this.IRegShort = ireg.ToString();
            this.IReg      = ireg.ToString_Frame_Use(); // The real ToString() is in use with a substring in it.  This is needed for proper operation
            this.MReg      = mreg.ToString_Frame_Use();
            this.OReg      = oreg.ToString_Frame_Use();
            this.PC        = pc.ToString().Substring(4, 4);
            this.ALU       = alu.ToString();
            this.WBus      = wbus_string;

            this.Overflow_Flag  = flags.Overflow.ToString();
            this.Underflow_Flag = flags.Underflow.ToString();
            this.Zero_Flag      = flags.Zero.ToString();

            foreach (string s in ramContents)
            {
                RAM.Add(s);
            }

            this.SEQ     = seq.ToString();
            this.WBus    = wbus_string; // I didnt want to mess with the Singleton in the frame, so the value will just be passed as a string
            this.RAM_Reg = ram.ToString_Frame_Use();

            if (instruction.Length == 0)
            {
                this.IReg = "???";
            }

            if (TState > 3)
            {
                //Instruction = OpCodeLoader.DecodeInstruction(IReg.Substring(0, 4), SetName); // TODO this is really inifeciant.  Should prob make a service and inject it
                Instruction = decoder.Decode(IReg.Substring(0, 4), SetName);
            }
            else
            {
                Instruction = "???";
            }
        }
Пример #3
0
        // *************************************************************************

        // *************************************************************************
        // Engine Runtime
        // *************************************************************************
        public void Run()
        {
            //Log.Information("SAP1Emu: Begin Engine Run");

            //Log.Verbose("SAP1Emu: Initializing Registers");
            Clock  clock  = new Clock();
            TicTok tictok = new TicTok();

            tictok.Init();

            AReg areg = new AReg();
            BReg breg = new BReg();
            IReg ireg = new IReg();
            OReg oreg = new OReg();
            RAM  ram  = new RAM();

            PC   pc   = new PC(ref areg);
            ALU  alu  = new ALU(ref areg, ref breg);
            MReg mreg = new MReg(ref ram);
            SEQ  seq  = SEQ.Instance();

            Wbus.Instance().Value = "00000000";
            Flags.Instance().Clear();

            areg.Subscribe(clock);
            breg.Subscribe(clock);
            ireg.Subscribe(clock);
            mreg.Subscribe(clock);
            oreg.Subscribe(clock);
            pc.Subscribe(clock);
            alu.Subscribe(clock); // ALU must come after A and B
            ram.Subscribe(clock);

            //  Log.Verbose("SAP1Emu: Initialized Registers");

            //   Log.Information("SAP1Emu: Loading Ram");
            // Load the program into the RAM
            ram.LoadProgram(Program);
            //    Log.Information("SAP1Emu: RAM:\n{RAM}", Program.RamContents);

            // Load the intsructionSet into the SEQ
            seq.Load(InstructionSet);
            //    Log.Information($"SAP1Emu: Loaded Instruction Set: \"{InstructionSet.SetName}\"");

            Frame tempFrame;

            #region Program_Exec

            // Since T1-T3 for all of the Intruction is the same,
            // LDA or "0000" will be used as the intruction for all T1-T3's
            clock.IsEnabled = true;

            // TODO: Cleanup old code stubs
            // These vars will make sure that the engine will not hang if there is an infinite loop
            // int warning1_loop_counter = 3000;
            // int warning2_loop_counter = 5000;
            // int warning3_loop_counter = 7000;
            // int warning4_loop_counter = 9000;
            int max_loop_count = 10000;
            int loop_counter   = 0;

            int TState = 1;
            //  Log.Information("SAP1Emu: Start Program Execution");
            while (clock.IsEnabled)
            {
                if (TState <= 3)
                {
                    seq.UpdateControlWordReg(TState, "0000");
                }
                else
                {
                    seq.UpdateControlWordReg(TState, ireg.ToString());
                }

                // Log the Instruction
                if (TState == 4)
                {
                    string iname      = InstructionSet.Instructions.Find(x => x.BinCode.Equals(ireg.ToString())).OpCode;
                    int    operandVal = Convert.ToInt32(ireg.ToString_Frame_Use().Substring(4, 4), 2);
                    string hexOperand = "0x" + operandVal.ToString("X");
                    //    Log.Information($"SAP1Emu: Instruction: {iname}, Operand: {hexOperand}");
                }

                clock.SendTicTok(tictok);
                tictok.ToggleClockState();
                clock.SendTicTok(tictok);
                tictok.ToggleClockState();
                tempFrame = new Frame(ireg.ToString(), TState, areg, breg, ireg, mreg, oreg, pc, alu, ram.RAMDump(), ram, seq, Wbus.Instance().ToString(), Flags.Instance(), _decoder, InstructionSet.SetName);
                _FrameStack.Add(tempFrame);

                if (ireg.ToString() == "1111" && TState == 6)
                {
                    // Log.Information("SAP1Emu: HLT Detected");
                    clock.IsEnabled = false;
                }
                // Infinite Loop Checks
                //if(loop_counter == warning1_loop_counter)
                //{
                //    Log.Warning($"SAP1Emu: Infinite Loop Warning: interations count: {warning1_loop_counter} ");
                //}
                //else if (loop_counter == warning2_loop_counter)
                //{
                //    Log.Warning($"SAP1Emu: Infinite Loop Warning: interations count: {warning2_loop_counter} ");
                //}
                //else if (loop_counter == warning3_loop_counter)
                //{
                //    Log.Warning($"SAP1Emu: Infinite Loop Warning: interations count: {warning3_loop_counter} ");
                //}
                //else if (loop_counter == warning4_loop_counter)
                //{
                //    Log.Warning($"SAP1Emu: Infinite Loop Warning: interations count: {warning4_loop_counter} ");
                //}

                if (loop_counter >= max_loop_count)
                {
                    // Log.Fatal($"SAP1Emu: Infinite Loop Fatal Error: Infinite Loop Detected");
                    // Log.CloseAndFlush();
                    throw new EngineRuntimeException("Engine Error: Infinite Loop Detected");
                }
                else
                {
                    loop_counter++;
                }

                if (TState < 6)
                {
                    TState++;
                }
                else
                {
                    TState = 1;
                }
            }
            // Log.Information("SAP1Emu: End Program Execution");

            OutPutRegContents = oreg.ToString();
            //  Log.Information("SAP1Emu: End Engine Run");

            //  Log.CloseAndFlush();

            #endregion Program_Exec
        }