SilverOS handles all human input through the legacy PS/2 controller (Intel 8042). The keyboard driver is wired to IRQ1 and the mouse driver to IRQ12; both use interrupt-driven ring buffers so the kernel never needs to poll the hardware in a spin loop. Scancodes are translated to ASCII or to named special-key constants at interrupt time, and the results are deposited into a 256-byte ring buffer for the main loop to consume at its own pace.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/pastaboy12345/SilverOS/llms.txt
Use this file to discover all available pages before exploring further.
Keyboard driver
The keyboard interrupt handler (IRQ1) reads a raw scancode from I/O port 0x60 on every keypress or key-release event. Make-codes (key presses) are mapped to ASCII characters using the US QWERTY Scancode Set 1 translation tables built into the driver. Break-codes (key releases, scancode | 0x80) are used only to track the state of modifier keys — they are never placed in the ring buffer.
Three modifier states are tracked globally:
- Shift — either left shift (0x2A) or right shift (0x36) sets
shift_held; the corresponding break-code clears it. - Ctrl — left control (0x1D) sets
ctrl_held; its break-code clears it. - Caps Lock — scancode 0x3A toggles
caps_lock; the driver XORs this withshift_heldto determine case for letter keys.
keyboard.h:
| Function | Description |
|---|---|
keyboard_init | Registers the IRQ1 handler in the IDT and unmasks IRQ1 in the PIC. Logs [KEYBOARD] PS/2 keyboard initialized to the serial port. |
keyboard_getchar | Blocks until a character is available in the ring buffer, then dequeues and returns it. |
keyboard_haschar | Returns non-zero if at least one character is waiting in the buffer. Safe to call from the main event loop. |
keyboard_getchar_nb | Dequeues and returns the next character, or 0 if the buffer is empty. Intended for non-blocking polling. |
keyboard_shift_pressed | Returns the current state of either Shift key. |
keyboard_ctrl_pressed | Returns the current state of the left Ctrl key. |
Reading keyboard input
For contexts that can afford to block — such as a text prompt before the desktop starts — usekeyboard_getchar() directly:
keyboard_getchar blocks by executing hlt inside a spin loop — the CPU is halted and resumes only when the next interrupt fires. This is appropriate for single-purpose blocking prompts, but must never be called from inside the desktop rendering loop, as it will stall all drawing and mouse handling until a key is pressed. Use keyboard_getchar_nb in any context that has a frame loop.Mouse driver
The PS/2 mouse is enabled through the 8042 controller and fires IRQ12. The driver accumulates the three-byte mouse packet, updates an internalmouse_state_t struct, and clamps the cursor position to the screen bounds derived from fb.width and fb.height.
| Function | Description |
|---|---|
mouse_init | Enables the PS/2 auxiliary device via the 8042 command port, resets it to default settings, enables data reporting, registers the IRQ12 handler, and unmasks IRQ12 in the PIC. |
mouse_get_state | Copies the current internal mouse state into the caller-supplied mouse_state_t. This is a non-blocking snapshot — safe to call every frame. |
mouse_clear_clicks | Clears the left_clicked and left_released one-shot flags. Must be called after handling a click event to prevent it from being processed on every subsequent frame. |
left_button and left_clicked is important:
left_buttonistruefor as long as the button is physically held down. Use this for drag operations.left_clickedistrueonly for frames after the button was first pressed, untilmouse_clear_clicks()is called. Use this for single-action click events like button presses and icon activations.
[0, fb.width - 1] × [0, fb.height - 1] by the IRQ12 handler, so ms.x and ms.y are always valid pixel positions regardless of how fast the mouse is moved.
Mouse usage in the desktop event loop
fb_swap_buffers(). Because mouse_get_state copies the state atomically, the cursor position seen during rendering is consistent throughout the frame even if the IRQ12 handler fires mid-frame.