Feature: PS/2 micocrontroller, full INT9H, fixed Avalonia keyboard enum usage, fix UI/Emu input thread race, full keyboard command and code sets#1527
Conversation
f8a6725 to
343a63b
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive PS/2 keyboard emulation system, replacing the basic keyboard implementation with a full Intel 8042 controller, PS/2 keyboard device, and proper interrupt handling. The changes address keyboard input thread safety, typematic behavior, scancode translation, and keyboard command processing.
- Replaced simple
Keyboardclass withIntel8042ControllerandPS2Keyboardfor authentic hardware emulation - Introduced
InputEventHubto queue keyboard/mouse events and process them safely on the emulation thread - Split monolithic
IGuiinterface into focused interfaces (IGuiVideoPresentation,IGuiKeyboardEvents,IGuiMouseEvents) - Implemented full INT 09H keyboard interrupt handler with BIOS keyboard buffer management and status flag tracking
Reviewed Changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/Spice86/ViewModels/Services/AvaloniaKeyScanCodeConverter.cs |
Removed - scancode conversion now handled by emulator core |
src/Spice86/ViewModels/MainWindowViewModel.cs |
Updated to use PhysicalKey enum and removed scancode/ASCII conversion logic |
src/Spice86/ViewModels/HeadlessGui.cs |
Updated to implement split GUI interfaces |
src/Spice86/Spice86DependencyInjection.cs |
Wired up new Intel8042Controller and InputEventHub with dependency injection |
src/Spice86.Shared/Interfaces/* |
Refactored IGui into focused interfaces for separation of concerns |
src/Spice86.Shared/Emulator/Keyboard/PhysicalKey.cs |
New enum mapping W3C physical key codes to keyboard positions |
src/Spice86.Shared/Emulator/Keyboard/KeyboardEventArgs.cs |
Simplified to use PhysicalKey without scancode/ASCII |
src/Spice86.Core/Emulator/VM/Machine.cs |
Renamed Keyboard property to KeyboardController |
src/Spice86.Core/Emulator/VM/InputEventQueue.cs |
New thread-safe event queue for UI-to-emulation input |
src/Spice86.Core/Emulator/VM/EmulationLoop.cs |
Processes queued input events each slice |
src/Spice86.Core/Emulator/InterruptHandlers/Input/Keyboard/BiosKeyboardInt9Handler.cs |
Complete INT 09H implementation with scancode processing and keyboard intercept |
src/Spice86.Core/Emulator/InterruptHandlers/Bios/SystemBiosInt15Handler.cs |
Added INT 15H AH=4Fh keyboard intercept function |
src/Spice86.Core/Emulator/Devices/Input/Keyboard/Intel8042Controller.cs |
Full 8042 controller with command processing, A20 gate control, and port management |
src/Spice86.Core/Emulator/Devices/Input/Keyboard/PS2Keyboard.cs |
PS/2 keyboard with typematic, LED control, and scancode set support |
src/Spice86.Core/Emulator/Devices/Input/Keyboard/KeyboardScancodeConverter.cs |
Converts PhysicalKey to scancode sets 1/2/3 |
tests/Spice86.Tests/Dos/DosFileManagerTests.cs |
Updated test setup for new keyboard architecture |
4314c89 to
13ba4fb
Compare
b03171b to
472ee6f
Compare
Updated the PS2Keyboard, Mouse, VgaCard, and MouseDriver classes to use more specific interfaces for handling keyboard, mouse, and video events. Removed the IGui interface and introduced IGuiKeyboardEvents, IGuiMouseEvents, and IGuiVideoPresentation for better separation of concerns. The HeadlessGui class now implements these new interfaces, and the Spice86DependencyInjection and MainWindowViewModel classes were modified accordingly to support the changes.
- Introduced `InputEventQueue` for processing keyboard and mouse events in a thread-safe manner. - Updated `EmulationLoop` to include `_inputEventQueue` and modified its constructor to accept this new parameter. - Enhanced the main execution method of `EmulationLoop` to process input events during each iteration. - Updated documentation for the `IsPaused` property for clarity. - Modified `Spice86DependencyInjection` and `DosFileManagerTests` to integrate the new input event handling functionality.
6a4ac09 to
600f9c0
Compare
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
xorangekiller
left a comment
There was a problem hiding this comment.
I'm certainly not an expert on anything being modified here, but I did my best to review it, and I don't see any problems.
I also tried it out with Exodus, and it seems to fix the keyboard issues I had with it before. For example, if I hold down the spacebar to shoot while using the arrow keys to move, it works now without stuttering or stopping, which it doesn't on master. This is definitely a big improvement, and I think that it makes Exodus playable enough that I could probably beat most levels with it now.
| if ((isFromKbd && _config.TranslationEnabled)) { | ||
| entry.Data = GetTranslated(value); | ||
| } else { | ||
| entry.Data = value; | ||
| } |
Check notice
Code scanning / CodeQL
Missed ternary opportunity Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 months ago
To fix this problem, replace the if statement on line 342 and its corresponding else-block (lines 342–346) with a single assignment statement to entry.Data using the ternary (? :) operator. This change should remain entirely within the confines of the presented code, specifically the method BufferAdd in src/Spice86.Core/Emulator/Devices/Input/Keyboard/Intel8042Controller.cs. This fix preserves existing functionality and improves readability, with no modifications needed elsewhere in the file.
| @@ -339,11 +339,7 @@ | ||
| } | ||
|
|
||
| var entry = new BufferEntry(); | ||
| if ((isFromKbd && _config.TranslationEnabled)) { | ||
| entry.Data = GetTranslated(value); | ||
| } else { | ||
| entry.Data = value; | ||
| } | ||
| entry.Data = (isFromKbd && _config.TranslationEnabled) ? GetTranslated(value) : value; | ||
| entry.IsFromAux = isFromAux; | ||
| entry.IsFromKbd = isFromKbd; | ||
| entry.SkipDelay = skipDelay || (!isFromAux && !isFromKbd); |
Description of Changes
Implements the full PS/2 micro controller (INTEL 8049 chip), the internal keyboard buffer, the proper UI VS Emu thread concurrent input queue access handling, typematic events, keyboard delay event, keyboard reset event, code sets, and IBM AT vs XT code set conversions, and keyboard key interception (can be overriden by TSRs), and all the keyboard commands.
Rationale behind Changes
Implements most of #329
Previously, the PS/2 micro controller, and full INT9H were partially or entirely unimplemented. Same for the rest.
It should vastly improve the usability and compatibility of the keyboard and PS/2 micro controller emulation.
It already makes the keyboard easier to use, but there is still a big DOS issue with a key IOCTL INT21H function to fix for the DOS console.
The reason why essentially is that the keyboard event flow now properly flows from: UI → InputEventQueue → EmulationLoop.ProcessAllPendingInputEvents() → PS2Keyboard → BIOS keyboard buffer.
Since this is focused on hardware, I left DOS out of this PR.
Suggested Testing Steps
Already tested with:
Dune
Dune 2
Jill of the Jungle
Krondor
Hocus Pocus
Another World
Compared to master, it's especially better with Jill of the Jungle.
Skipped
DOS Console issues...
DOS Codepage issue...
Mouse AUX and mouse notifications, and mouse frame...
Print Screen special support...
Pause key special support...