public byte Read(int port) { if (port == PORT_CONTROL) { throw new InvalidOperationException(); } if (port == PORT_COUNT0) { return(CountZero.Read()); } else if (port == PORT_COUNT1) { return(CountOne.Read()); } else if (port == PORT_COUNT2) { return(CountTwo.Read()); } else if (port == PORT_STATUS) { if (_timerHack.Count > 0) { return(_timerHack.Dequeue()); } return((byte)((timerZero ? 1 : 0) + ((timerOne ? 1 : 0) << 1))); } throw new InvalidOperationException(); }
public void Step(double us) { _us += us; if (_us >= CLK_US) { var beforeZero = CountZero.Output; CountZero.Pulse(); if (!beforeZero && CountZero.Output && CountZero.Active) { CountOne.Pulse(); } CountTwo.Pulse(); if (CountZero.Output && CountZero.Active) { timerZero = true; } if (CountTwo.Output && CountTwo.Active) { timerOne = true; } _us -= CLK_US; } }
public void Write(int port, byte data) { if (port == PORT_CONTROL) { Counter counter = null; var counterNum = (data >> CTL_SEL_SHIFT) & CTL_SEL_MASK; var readLoad = (data >> CTL_RL_SHIFT) & CTL_RL_MASK; var mode = (data >> CTL_MODE_SHIFT) & CTL_MODE_MASK; var bcd = (data & 1) == 1; if (counterNum == 0) { counter = CountZero; } else if (counterNum == 1) { counter = CountOne; } else if (counterNum == 2) { counter = CountTwo; } counter.ReadLoad = (CounterReadLoad)readLoad; counter.Mode = (CounterMode)mode; counter.BCD = bcd; if (counter.Mode == CounterMode.Mode0 && counter.ReadLoad != CounterReadLoad.Latch) { counter.Value = counter.LastWrittenValue; } if (counterNum != 1) { counter.Active = false; } if (bcd) { throw new NotImplementedException(); } if (counter.ReadLoad == CounterReadLoad.Latch) { counter.LatchedValue = counter.Value; } } else if (port == PORT_COUNT0) { timerZero = false; CountZero.Write(data); } else if (port == PORT_COUNT1) { //this is a hack CountOne.Value = 250; CountOne.LastWrittenValue = 250; CountOne.Active = true; //CountOne.Write(data); } else if (port == PORT_COUNT2) { timerOne = false; CountTwo.Write(data); } else if (port == PORT_STATUS) { timerZero = timerZero && (data & 1) == 1; timerOne = timerOne && (data & 2) == 2; } }