using System.Collections.Generic; using Contralto.CPU; using Contralto.IO; using Contralto.Memory; using Contralto.Display; using System.Timers; namespace Contralto { /// /// Encapsulates all Alto hardware; represents a complete Alto system. /// Provides interfaces for controlling and debugging the system externally. /// public class AltoSystem { public AltoSystem() { _scheduler = new Scheduler(); _cpu = new AltoCPU(this); _memBus = new MemoryBus(); _mem = new Memory.Memory(); _keyboard = new Keyboard(); _diskController = new DiskController(this); _displayController = new DisplayController(this); //_fakeDisplayController = new FakeDisplayController(this); // Attach memory-mapped devices to the bus _memBus.AddDevice(_mem); _memBus.AddDevice(_keyboard); // Register devices that need clocks _clockableDevices = new List(); _clockableDevices.Add(_memBus); _clockableDevices.Add(_displayController); //_clockableDevices.Add(_fakeDisplayController); _clockableDevices.Add(_cpu); Reset(); Timer t = new Timer(); t.AutoReset = true; t.Interval = 1000; t.Elapsed += T_Elapsed; t.Start(); } public void Reset() { _scheduler.Reset(); _cpu.Reset(); _memBus.Reset(); _mem.Reset(); ALU.Reset(); Shifter.Reset(); _diskController.Reset(); _displayController.Reset(); } /// /// Attaches an emulated display device to the system. /// TODO: This is currently tightly-coupled with the Debugger, make /// more general. /// /// public void AttachDisplay(Debugger d) { _displayController.AttachDisplay(d); // _fakeDisplayController.AttachDisplay(d); } public void SingleStep() { // Run every device that needs attention for a single clock cycle. int count = _clockableDevices.Count; for (int i = 0; i < count; i++) { _clockableDevices[i].Clock(); } _scheduler.Clock(); _clocks++; } public AltoCPU CPU { get { return _cpu; } } public MemoryBus MemoryBus { get { return _memBus; } } public DiskController DiskController { get { return _diskController; } } public DisplayController DisplayController { get { return _displayController; } } public Keyboard Keyboard { get { return _keyboard; } } public Scheduler Scheduler { get { return _scheduler; } } /// /// Time (in msec) for one system clock /// /// public static double ClockInterval { get { return 0.00017; } // appx 170nsec, TODO: more accurate value? } private void T_Elapsed(object sender, ElapsedEventArgs e) { System.Console.WriteLine("{0} CPU clocks/sec %{1}. {2} fields/sec", _clocks, ((double)_clocks / 5882353.0) * 100.0, _displayController.Fields); _clocks = 0; _displayController.Fields = 0; } private AltoCPU _cpu; private MemoryBus _memBus; private Contralto.Memory.Memory _mem; private Keyboard _keyboard; private DiskController _diskController; private DisplayController _displayController; // private FakeDisplayController _fakeDisplayController; private Scheduler _scheduler; private ulong _clocks; private List _clockableDevices; } }