diff --git a/imlac/IImlacConsole.cs b/imlac/IImlacConsole.cs index 153c1f8..31d0c7b 100644 --- a/imlac/IImlacConsole.cs +++ b/imlac/IImlacConsole.cs @@ -144,7 +144,7 @@ namespace imlac /// /// Indicates whether a key is currently pressed. /// - bool IsKeyPressed + bool NewKeyPressed { get; } diff --git a/imlac/IO/Keyboard.cs b/imlac/IO/Keyboard.cs index 0e7acba..4477486 100644 --- a/imlac/IO/Keyboard.cs +++ b/imlac/IO/Keyboard.cs @@ -31,6 +31,7 @@ namespace imlac.IO public enum ImlacKey { + None = 0x0, DataXmit = 0x2, Down = 0x4, Right = 0x5, @@ -118,25 +119,18 @@ namespace imlac.IO public void Clock() { // If we do not already have a key latched and one has been pressed, - // we will latch it now. - // Based on the keycode & modifiers we will generate an Imlac keyboard code + // we will raise the Ready flag now. if (!_keyReady) { - if (_system.Display.IsKeyPressed) - { - _keyCode = GetScancodeForCurrentKey(); - if (_keyCode != 0) - { - Trace.Log(LogType.Keyboard, "Key latched {0}", Helpers.ToOctal(_keyCode)); - _keyReady = true; - } + if (_system.Display.NewKeyPressed) + { + _keyReady = true; } } } public void Reset() { - _keyCode = 0; _keyReady = false; } @@ -155,20 +149,18 @@ namespace imlac.IO switch (iotCode) { case 0x11: - _system.Processor.AC |= _keyCode; + _system.Processor.AC |= GetScancodeForCurrentKey(); Trace.Log(LogType.Keyboard, "Key OR'd into AC {0}", Helpers.ToOctal(_system.Processor.AC)); break; case 0x12: - _keyCode = 0; _keyReady = false; _system.Display.UnlatchKey(); Trace.Log(LogType.Keyboard, "Keyboard flag reset."); break; case 0x13: - _system.Processor.AC |= _keyCode; - _keyCode = 0; + _system.Processor.AC |= GetScancodeForCurrentKey(); _keyReady = false; _system.Display.UnlatchKey(); Trace.Log(LogType.Keyboard, "Key OR'd into AC {0}, keyboard flag reset.", Helpers.ToOctal(_system.Processor.AC)); @@ -196,7 +188,7 @@ namespace imlac.IO // bit 8 is always set scanCode = (ushort)(scanCode | 0x80); - + // // The Repeat, Control, and Shift keys correspond to bits 5, 6, and 7 of the // scancode returned. @@ -225,7 +217,6 @@ namespace imlac.IO private readonly int[] _handledIOTs = { 0x11, 0x12, 0x13 }; private bool _keyReady; - private ushort _keyCode; private ImlacSystem _system; @@ -247,6 +238,7 @@ namespace imlac.IO { _keyMappings = new Dictionary(); + AddMapping(ImlacKey.None, 0x0, 0x0); AddMapping(ImlacKey.DataXmit, 0x2, 0x0); AddMapping(ImlacKey.Down, 0x4, 0x0); AddMapping(ImlacKey.Right, 0x5, 0x0); diff --git a/imlac/IO/TTY.cs b/imlac/IO/TTY.cs index a1aceea..7ea9c43 100644 --- a/imlac/IO/TTY.cs +++ b/imlac/IO/TTY.cs @@ -171,7 +171,7 @@ namespace imlac.IO private byte _txData; private int _clocks; - private readonly int _dataClocks = 500; + private readonly int _dataClocks = 90; // Appx. 50kbps private ISerialDataChannel _dataChannel; diff --git a/imlac/SDLConsole.cs b/imlac/SDLConsole.cs index 3ba38c0..96f0560 100644 --- a/imlac/SDLConsole.cs +++ b/imlac/SDLConsole.cs @@ -91,20 +91,20 @@ namespace imlac BuildKeyMappings(); } - public bool IsKeyPressed + public bool NewKeyPressed { get { _keyLatchedLock.EnterReadLock(); - bool latched = _keyLatched; + bool pressed = _newKeyPressed; _keyLatchedLock.ExitReadLock(); - return latched; + return pressed; } } public ImlacKey Key { - get { return _latchedKeyCode; } + get { return _currentKeyCode; } } public ImlacKeyModifiers KeyModifiers @@ -114,9 +114,8 @@ namespace imlac public void UnlatchKey() { - _keyLatchedLock.EnterReadLock(); - _keyLatched = false; - _latchedKeyCode = ImlacKey.Invalid; + _keyLatchedLock.EnterReadLock(); + _newKeyPressed = false; _keyLatchedLock.ExitReadLock(); } @@ -478,17 +477,21 @@ namespace imlac _keyLatchedLock.EnterWriteLock(); - if (!_keyLatched) + // Only accept this key if we're not waiting + // for the Imlac to read the last one. + if (!_newKeyPressed) { ImlacKey newCode = TranslateKeyCode(key); // Only latch valid keys. if (newCode != ImlacKey.Invalid) { - _keyLatched = true; - _latchedKeyCode = newCode; + _newKeyPressed = true; + _currentKeyCode = newCode; } } + + _keyPressedCount++; _keyLatchedLock.ExitWriteLock(); break; } @@ -518,9 +521,16 @@ namespace imlac _keyLatchedLock.EnterWriteLock(); - if (!_keyLatched) + // + // Decrement our pressed keycount, when this reaches zero + // this means the last pressed key has been released and we + // can set the keycode to None to indicate no keys being down. + // (This avoids issues with n-key rollover.) + // + _keyPressedCount--; + if (_keyPressedCount == 0) { - _latchedKeyCode = ImlacKey.Invalid; + _currentKeyCode = ImlacKey.None; } _keyLatchedLock.ExitWriteLock(); @@ -675,17 +685,17 @@ namespace imlac public void Draw(IntPtr sdlRenderer, bool blinkOn) { // TODO: handle dotted lines, line thickness options - + if (!_blink || blinkOn) { SDL.SDL_SetRenderDrawColor( - sdlRenderer, - (byte)(_color.R * _intensity), - (byte)(_color.G * _intensity), - (byte)(_color.B * _intensity), - _color.A); + sdlRenderer, + (byte)(_color.R * _intensity), + (byte)(_color.G * _intensity), + (byte)(_color.B * _intensity), + _color.A); - SDL.SDL_RenderDrawLine(sdlRenderer, _x1, _y1, _x2, _y2); + SDL.SDL_RenderDrawLine(sdlRenderer, _x1, _y1, _x2, _y2); } } @@ -953,9 +963,10 @@ namespace imlac private static Dictionary _sdlImlacKeymap; private static Dictionary _sdlVKeymap; - private ImlacKey _latchedKeyCode; + private ImlacKey _currentKeyCode; private ImlacKeyModifiers _keyModifiers; - private bool _keyLatched; + private int _keyPressedCount; + private bool _newKeyPressed; private ReaderWriterLockSlim _keyLatchedLock;