예제 #1
0
 /// <summary>
 /// Writes the given databus value to the register determined by the micro program memory entry.
 /// </summary>
 /// <param name="session"></param>
 /// <param name="mpmEntry">Current micro program memory entry</param>
 /// <param name="dataBus">DataBus value</param>
 private void WriteDataBusToRegister(IProcessorSession session, IMicroInstruction mpmEntry, uint dataBus)
 {
     Registers target;
     switch (mpmEntry.Destination)
     {
         case Destination.Empty:
             return;
         case Destination.SELReferenced:
             target = GetSELReferenced(session.Processor);
             break;
         case Destination.MDR:
             if (mpmEntry.ReadWrite == ReadWrite.Write)
             {
                 var memoryAddress = (byte)session.Processor.Registers[Registers.MAR].Value;
                 if (mpmEntry.DataInput == DataInput.IO)
                 {
                     var devices = session.DeviceManager.Devices;
                     if (devices.ContainsKey(memoryAddress)) { devices[memoryAddress].Input((byte)dataBus); }
                 }
                 else { session.RamSession.Set(memoryAddress, (byte)dataBus); }
             }
             target = Registers.MDR;
             break;
         default:
             target = (Registers)mpmEntry.Destination;
             break;
     }
     session.SetRegister(target, dataBus);
 }
예제 #2
0
 /// <summary>
 /// Calculates the next micro instruction pointer (MIP).
 /// This is calculated from the processor state and the current micro program memory entry.
 /// </summary>
 /// <param name="session"></param>
 /// <param name="mpmEntry">Current micro program memory entry</param>
 /// <returns>New micro instruction pointer</returns>
 private uint NextMip(IProcessor processor, IMicroInstruction mpmEntry)
 {
     var mip = processor.Registers[Registers.MIP].Value;
     var status = new StatusRegister(processor.Registers[Registers.Status]);
     switch (mpmEntry.NextAddress)
     {
         case NextAddress.Next:
             return mip + (uint)(SuccessfulJump(status, mpmEntry.JumpCriterion) ? mpmEntry.Value : 1);
         case NextAddress.Decode:
             var instruction = processor.Registers[Registers.IR].Value;
             return (uint)mpm.Instructions[(byte)instruction].MpmAddress;
         case NextAddress.Fetch:
             var interrupt = processor.Registers[Registers.Interrupt];
             return (status.Interrupt && interrupt.Value == 1) ? InterruptAddress : FetchAddress;
         default:
             throw new NotImplementedException();
     }
 }
예제 #3
0
 /// <summary>
 /// Returns the value, which is currently active on the databus.
 /// </summary>
 /// <param name="processor"></param>
 /// <param name="mpmEntry">Current micro program memory entry</param>
 /// <returns>DataBus value</returns>
 private uint GetDataBusValue(IProcessorSession session, IMicroInstruction mpmEntry)
 {
     var processor = session.Processor;
     switch (mpmEntry.Source)
     {
         case Source.Empty:
             return 0;
         case Source.Data:
             var memoryAddress = (byte)processor.Registers[Registers.MAR].Value;
             if (mpmEntry.DataInput == DataInput.IO)
             {
                 var devices = session.DeviceManager.Devices;
                 if (devices.ContainsKey(memoryAddress)) { return devices[memoryAddress].Output(); }
                 else { return 0; }
             }
             else
             {
                 return processor.Ram.Data[memoryAddress];
             }
         case Source.SELReferenced:
             return processor.Registers[GetSELReferenced(processor)].Value;
         default:
             return processor.Registers[(Registers)mpmEntry.Source].Value;
     }
 }
예제 #4
0
 /// <summary>
 /// Checks if the processor reched a state in which it should be halted.
 /// </summary>
 /// <param name="mpmEntry"></param>
 /// <param name="processor"></param>
 /// <returns></returns>
 private bool IsHalt(IMicroInstruction mpmEntry, IProcessor processor) => mpmEntry.NextAddress == NextAddress.Decode && processor.Registers[Registers.IR].Value == 0;