2025-05-28 14:41:02 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <port_io.h>
|
2025-06-13 19:53:54 -05:00
|
|
|
#include <tty.h>
|
2025-05-28 14:41:02 -05:00
|
|
|
|
|
|
|
#include <drivers/ps2_keyboard.h>
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2025-06-13 18:03:39 -05:00
|
|
|
PS/2 Controller IO Ports
|
2025-05-28 14:41:02 -05:00
|
|
|
|
2025-06-13 18:03:39 -05:00
|
|
|
The PS/2 Controller itself uses 2 IO ports (IO ports 0x60 and 0x64). Like many IO ports, reads and writes may access different internal registers.
|
2025-05-28 14:41:02 -05:00
|
|
|
|
2025-06-13 18:03:39 -05:00
|
|
|
Historical note: The PC-XT PPI had used port 0x61 to reset the keyboard interrupt request signal (among other unrelated functions). Port 0x61 has no keyboard related functions on AT and PS/2 compatibles.
|
|
|
|
IO Port Access Type Purpose
|
|
|
|
0x60 Read/Write Data Port
|
|
|
|
0x64 Read Status Register
|
|
|
|
0x64 Write Command Register
|
2025-05-28 14:41:02 -05:00
|
|
|
*/
|
|
|
|
|
2025-06-13 19:53:54 -05:00
|
|
|
/*
|
|
|
|
Note:
|
|
|
|
The interrupt number for keyboard input in 1.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define PS2_DATA_PORT 0x60
|
|
|
|
#define PS2_STATUS_PORT 0x64
|
|
|
|
|
|
|
|
#define KEYBOARD_IRQ 1
|
|
|
|
|
|
|
|
|
|
|
|
/* State for shift key */
|
|
|
|
static bool shift_pressed = false;
|
|
|
|
|
|
|
|
static const char scancode_map[128] = {
|
|
|
|
0, 27, '1','2','3','4','5','6','7','8','9','0','-','=','\b', /* Backspace */
|
|
|
|
'\t', // Tab
|
|
|
|
'q','w','e','r','t','y','u','i','o','p','[',']','\n', /* Enter */
|
|
|
|
0, /* Control */
|
|
|
|
'a','s','d','f','g','h','j','k','l',';','\'','`',
|
|
|
|
0, /* Left shift */
|
|
|
|
'\\','z','x','c','v','b','n','m',',','.','/',
|
|
|
|
0, /* Right shift */
|
|
|
|
'*',
|
|
|
|
0, /* Alt */
|
|
|
|
' ', /* Spacebar */
|
|
|
|
0, /* Caps lock */
|
|
|
|
/* The rest are function and control keys */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2025-05-28 14:41:02 -05:00
|
|
|
void keyboard_init(void)
|
|
|
|
{
|
2025-06-13 19:53:54 -05:00
|
|
|
outb(0x64, 0xAE); /* Enable keyboard interface (often optional, but here for safety) */
|
|
|
|
}
|
|
|
|
|
|
|
|
void keyboard_handler(void) {
|
|
|
|
uint8_t scancode = inb(PS2_DATA_PORT);
|
|
|
|
|
|
|
|
/* Handle shift press/release */
|
|
|
|
if (scancode == 0x2A || scancode == 0x36)
|
|
|
|
{
|
|
|
|
shift_pressed = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (scancode == 0xAA || scancode == 0xB6)
|
|
|
|
{
|
|
|
|
shift_pressed = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scancode & 0x80)
|
|
|
|
{
|
|
|
|
/* Key release event, ignore for now */
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
char c = scancode_map[scancode];
|
|
|
|
if (shift_pressed && c >= 'a' && c <= 'z') {
|
|
|
|
c -= 32; /* Convert to uppercase */
|
|
|
|
}
|
|
|
|
else if (shift_pressed)
|
|
|
|
{
|
|
|
|
c = (char) terminal_get_shifted((unsigned char) c);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c)
|
|
|
|
{
|
|
|
|
printf("%c", c);
|
|
|
|
}
|
|
|
|
}
|
2025-05-28 14:41:02 -05:00
|
|
|
}
|