public void Exec(TicTok tictok) { var cw = SEQ.Instance().ControlWord; // Active Hi, Count on Tic if (string.Equals(cw["CP"], "1", StringComparison.Ordinal) && tictok.ClockState == TicTok.State.Tic) { int count = BinConverter.Bin8ToInt(RegContent); count++; RegContent = BinConverter.IntToBin16(count); } // Active Hi, Push on Tic if (string.Equals(cw["EP"], "1", StringComparison.Ordinal) && tictok.ClockState == TicTok.State.Tic) { // Send PC to the WBus Wbus.Instance().Value = RegContent; } // Active Low - Broadside Load, Pull if (string.Equals(cw["LP_"], "0", StringComparison.Ordinal) && tictok.ClockState == TicTok.State.Tok) { RegContent = Wbus.Instance().Value; } }
public void TestToString() { Clock clock = new Clock(); TicTok tictok = new TicTok(); tictok.Init();; int TState = 0; 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(); Frame frame = new Frame(ireg.ToString(), TState, areg, breg, ireg, mreg, oreg, pc, alu, ram.RAMDump(), ram, seq, Wbus.Instance().ToString(), Flags.Instance(), _decoder); _ = frame.ToString(); _ = frame.OutputRegister(); }
private void Exec(TicTok tictok) { var cw = SEQ.Instance().ControlWord; if (string.Equals(cw["CALL"], "1", StringComparison.Ordinal)) { // PC return address being set if (string.Equals(cw["RTNA"], "0", StringComparison.Ordinal)) { RegContent = Convert.ToString(0xFFFE - 0x0800 - 1, 2); ram.SetMARContent(RegContent); } else { RegContent = Convert.ToString(0xFFFF - 0x0800 - 1, 2); ram.SetMARContent(RegContent); } } // Active Low, Pull on Tok if (string.Equals(cw["LM_"], "0", StringComparison.Ordinal) && tictok.ClockState == TicTok.State.Tok) { // Store Wbus val in MAR RegContent = Wbus.Instance().Value; // Send the MAR data to the RAM ram.IncomingMARData(RegContent); } }
public static Wbus Instance() { if (_instance == null) { _instance = new Wbus(); } return(_instance); }
public void TestToString() { Clock clock = new Clock(); TicTok tictok = new TicTok(); tictok.Init(); int TState = 0; AReg areg = new AReg(); TReg treg = new TReg(); BReg breg = new BReg(); CReg creg = new CReg(); IReg ireg = new IReg(); IPort1 port1 = new IPort1(); IPort2 port2 = new IPort2(); MDR mdr = new MDR(); RAM ram = new RAM(); mdr.SetRefToRAM(ref ram); ALU alu = new ALU(ref areg, ref treg); OReg3 oreg3 = new OReg3(ref alu); OReg4 oreg4 = new OReg4(ref alu); HexadecimalDisplay hexadecimalDisplay = new HexadecimalDisplay(ref oreg3); Flag flagReg = new Flag(ref alu); PC pc = new PC(ref flagReg); MAR mar = new MAR(ref ram); SEQ seq = SEQ.Instance(); Wbus.Instance().Value = string.Concat(Enumerable.Repeat('0', 16)); Instruction currentInstruction = new Instruction { OpCode = "ADD B", BinCode = "10000000", TStates = 4, AffectsFlags = true, AddressingMode = AddressingMode.Register, Bytes = 1 }; Frame frame = new Frame(currentInstruction, TState, port1, port2, pc, mar, ram, ram.RAMDump(), mdr, ireg, SEQ.Instance(), Wbus.Instance().Value, areg, alu, flagReg, treg, breg, creg, oreg3, oreg4, hexadecimalDisplay); _ = frame.ToString(); _ = frame.OutputRegister(); }
public void TestUnsubscribe() { 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(); seq.Load(GetInstructionSet()); 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); for (int i = 0; i < 500; i++) { clock.SendTicTok(tictok); tictok.ToggleClockState(); clock.SendTicTok(tictok); tictok.ToggleClockState(); } // UnSub all clock.EndTransmission(); for (int i = 0; i < 500; i++) { clock.SendTicTok(tictok); tictok.ToggleClockState(); clock.SendTicTok(tictok); tictok.ToggleClockState(); } }
private void Exec(TicTok tictok) { string cw = SEQ.Instance().ControlWord; // TODO - Find a better way of using the mask to get the value // Currently is using hardcoded magic numbers // Active Low, Pull on Tok if (cw[11] == '0' && tictok.ClockState == TicTok.State.Tok) { // Store Wbus val in A RegContent = Wbus.Instance().Value; } }
public void TestUpdate() { try { 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(); seq.Load(GetInstructionSet()); 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); clock.IsEnabled = true; for (int i = 0; i < 500; i++) { clock.SendTicTok(tictok); tictok.ToggleClockState(); clock.SendTicTok(tictok); tictok.ToggleClockState(); } } catch (Exception e) { Assert.Fail(e.ToString()); } }
private void Exec(TicTok tictok) { string cw = SEQ.Instance().ControlWord; // TODO - Find a better way of using the mask to get the value // Currently is using hardcoded magic numbers // Active Low, Pull on Tok if (cw[2] == '0' && tictok.ClockState == TicTok.State.Tok) { // Store Wbus val in A RegContent = Wbus.Instance().Value.Substring(4, 4); // Send the MAR data to the RAM ram.IncomingMARData(RegContent); } }
private void Exec(TicTok tictok) { string cw = SEQ.Instance().ControlWord; // TODO - Find a better way of using the mask to get the value // Currently is using hardcoded magic numbers // Active Low, Push on Tic if (cw[5] == '0' & tictok.ClockState == TicTok.State.Tic) { // Send A to the WBus Wbus.Instance().Value = "0000" + RegContent.Substring(4, 4); //Instruction register only outputs the least significant bits to the WBus } // Active Low, Pull on Tok if (cw[4] == '0' && tictok.ClockState == TicTok.State.Tok) { RegContent = Wbus.Instance().Value; } }
// ************************************************************************* // ************************************************************************* // Engine Runtime // ************************************************************************* public void Run() { Clock clock = new Clock(); TicTok tictok = new TicTok(); tictok.Init(); AReg areg = new AReg(); TReg treg = new TReg(); BReg breg = new BReg(); CReg creg = new CReg(); IReg ireg = new IReg(); IPort1 iport1 = new IPort1(); IPort2 iport2 = new IPort2(); MDR mdr = new MDR(); RAM ram = new RAM(); mdr.SetRefToRAM(ref ram); ALU alu = new ALU(ref areg, ref treg); areg.SetALUReference(ref alu); breg.SetALUReference(ref alu); creg.SetALUReference(ref alu); OReg3 oreg3 = new OReg3(ref alu); OReg4 oreg4 = new OReg4(ref alu); HexadecimalDisplay hexadecimalDisplay = new HexadecimalDisplay(ref oreg3); Flag flagReg = new Flag(ref alu); PC pc = new PC(ref flagReg); MAR mar = new MAR(ref ram); SEQ seq = SEQ.Instance(); Wbus.Instance().Value = string.Concat(Enumerable.Repeat('0', 16)); areg.Subscribe(clock); treg.Subscribe(clock); breg.Subscribe(clock); creg.Subscribe(clock); ireg.Subscribe(clock); mar.Subscribe(clock); pc.Subscribe(clock); alu.Subscribe(clock); // ALU must come after A and T flagReg.Subscribe(clock); ram.Subscribe(clock); mdr.Subscribe(clock); oreg3.Subscribe(clock); hexadecimalDisplay.Subscribe(clock); oreg4.Subscribe(clock); // Load the program into the RAM ram.LoadProgram(Program); // Load the intsructionSet into the SEQ seq.Load(InstructionSet); 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; int max_loop_count = 10_000; int loop_counter = 0; int TState = 1; // A basic empty instruction state with 3 TStates since on the 4th the instruction // will be known and set to a new object reference. Instruction currentInstruction = new Instruction() { OpCode = "???", TStates = 4 // Since by 4 TStates it should know what instruction it is on }; List <string> controlWords = new List <string>(); bool? didntJump = null; while (clock.IsEnabled) { // Log the Instruction if (TState == 4) { currentInstruction = InstructionSet.Instructions.FirstOrDefault(i => i.BinCode.Equals(ireg.RegContent)); seq.LoadBackupControlWords(currentInstruction.MicroCode); string iname = currentInstruction.OpCode; int operandVal = Convert.ToInt32(ireg.RegContent, 2); string hexOperand = "0x" + operandVal.ToString("X"); } if (TState <= 3) { seq.UpdateControlWordReg(TState, "00000000", didntJump); if (didntJump ?? false) { pc.SkipByte(); didntJump = null; } } else { seq.UpdateControlWordReg(TState, ireg.RegContent); } clock.SendTicTok(tictok); tictok.ToggleClockState(); clock.SendTicTok(tictok); tictok.ToggleClockState(); tempFrame = new Frame(currentInstruction, TState, iport1, iport2, pc, mar, ram, ram.RAMDump(), mdr, ireg, SEQ.Instance(), Wbus.Instance().Value, areg, alu, flagReg, treg, breg, creg, oreg3, oreg4, hexadecimalDisplay); _FrameStack.Add(tempFrame); // HLT if (ireg.RegContent.Equals("01110110", StringComparison.Ordinal) && TState == 5) { clock.IsEnabled = false; _RAMDump = ram.RAMDump(); } if (loop_counter >= max_loop_count) { throw new EngineRuntimeException("Engine Error: Infinite Loop Detected"); } else { loop_counter++; } if (TState == 7 && currentInstruction.OpCode.StartsWith('J')) { pc.CheckForJumpCondition(); // PC is going to jump so do not let it fetch the next byte and immediately endx if (!pc.WontJump) { currentInstruction.TStates = 7; didntJump = true; } } if (TState < currentInstruction.TStates) { TState++; } else { TState = 1; currentInstruction = new Instruction() { OpCode = "???", TStates = 4 // Since by 4 TStates it should know what instruction it is on }; } } OutputReg = oreg3.ToString(); #endregion Program_Exec }
// ************************************************************************* // ************************************************************************* // 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 }
public void Exec(TicTok tictok) { string cw = SEQ.Instance().ControlWord; // Active Hi, Count on Tic if (cw[0] == '1' && tictok.ClockState == TicTok.State.Tic) { int count = BinConverter.Bin8ToInt(RegContent); count++; RegContent = BinConverter.IntToBin8(count); } // Active Hi, Push on Tic if (cw[1] == '1' & tictok.ClockState == TicTok.State.Tic) { // Send A to the WBus Wbus.Instance().Value = RegContent; } // Active Low - Broadside Load, Pull if (cw[13] == '0' & tictok.ClockState == TicTok.State.Tok) { string count = Wbus.Instance().Value; if (count.Length >= 8) { count = "0000" + count.Substring(4, 4); } // The cw[14-16] is a 3-bit jump code that tells the PC which jump code to preform. // JMP == 000 // JEQ == 001 // JNQ == 010 // JLT == 011 // JGT == 100 // JIC == 101 string jump_code = cw.Substring(14, 3); // JMP if (jump_code == "000") { this.RegContent = count; } // JEQ else if (jump_code == "001") { if (areg.ToString() == "00000000") { this.RegContent = count; } } // JNQ else if (jump_code == "010") { if (areg.ToString() != "00000000") { this.RegContent = count; } } // JLT else if (jump_code == "011") { if (areg.ToString()[0] == '1') { this.RegContent = count; } } // JGT else if (jump_code == "100") { if (areg.ToString() != "00000000" && areg.ToString()[0] == '0') { this.RegContent = count; } } // JIC else if (jump_code == "101") { if (Flags.Instance().Overflow == 1) { this.RegContent = count; } } } }