Browse Source

ps/2 wip

master
Mathieu Serandour 1 year ago
parent
commit
7957dd6a98
  1. 17
      kernel/drivers/azerty.s
  2. 61
      kernel/drivers/ps2kb.c
  3. 10
      kernel/drivers/ps2kb.h

17
kernel/drivers/azerty.s

@ -4,14 +4,14 @@
[section .rodata]
[global ps2_azerty_table_lowercase]
[global ps2_azerty_table_uppercase]
[global ps2_azerty_table_altgr]
ps2_azerty_table_lowercase:
db 0,0, "&e", '"', "'(-e_ca)=", 8
db 9, "azertyuiop^$", 10
db 0, "qsdfghjklmu", 0, 0, "*"
db "wxcvbn,;:!", 0,0
db 0,0, ' '
TIMES 80-53 db 0
db "wxcvbn,;:!", 0, 0
db 0, ' ',
TIMES 80-52 db 0
db "<"
ps2_azerty_table_uppercase:
@ -21,4 +21,11 @@ ps2_azerty_table_uppercase:
db "WXCVBN?./!", 0,0
db 0,0, ' '
TIMES 80-53 db 0
db "<"
db ">"
ps2_azerty_table_altgr:
db 0,0,0, "~#{[|`\^@]}", 8
db
TIMES 90-15 db 0

61
kernel/drivers/ps2kb.c

@ -8,11 +8,12 @@
static void kbevent_default_handler(const struct kbevent* event) {
(void) event;
log_debug("%c ", event->scancode);
}
static kbevent_handler handler = kbevent_default_handler;
static char lshift_state, rshift_state;
static char lshift_state, rshift_state, altgr_state;
static uint8_t get_byte(void) {
// wait for the output bufer
@ -23,13 +24,22 @@ static uint8_t get_byte(void) {
return inb(0x60);
}
static void flush_output_buffer(void) {
// wait for the output bufer
// to be empty
while((inb(0x64) & 1) != 0) {
inb(0x60);
}
}
// outputs a command to the controller
static void command_byte(uint8_t b) {
// wait for the input bufer
// to be empty
while((inb(0x64) & 2) == 1) {
while((inb(0x64) & 2) != 0) {
asm volatile("pause");
}
@ -40,6 +50,7 @@ static void command_byte(uint8_t b) {
extern const char ps2_azerty_table_lowercase[];
extern const char ps2_azerty_table_uppercase[];
extern const char ps2_azerty_table_altgr [];
@ -54,13 +65,26 @@ int is_caps(void) {
}
void ps2_trigger_CPU_reset(void) {
command_byte(0xFE);
// reset command
}
void ps2kb_poll_wait_for_key(uint8_t key) {
while(get_byte() != key)
;
}
static int process_leds(uint8_t b) {
if(b == 0xba) {// caps lock
// flush data buffer
inb(0x60);
leds_state = 0xff;
command_byte(0xED);
leds_state = leds_state ^ 4;
// io wait
outb(0x80, 0);
command_byte(leds_state);
return 1;
}
@ -92,22 +116,29 @@ static void process_byte(uint8_t b) {
rshift_state = ev.type;
return;
}
else if(ev.keycode == 56) {
altgr_state = ev.type;
}
if(is_caps())
if(altgr_state)
ev.scancode = ps2_azerty_table_altgr[ev.keycode];
else if(is_caps())
ev.scancode = ps2_azerty_table_uppercase[ev.keycode];
else
ev.scancode = ps2_azerty_table_lowercase[ev.keycode];
printf("%c", ev.scancode);
handler(&ev);
}
static void __attribute__((interrupt)) irq_handler(void* r) {
process_byte(inb(0x60));
uint8_t status = inb(0x64);
// sometimes, interrupts
// are triggered eventhough no
// key is pressed or released
if(status & 1)
process_byte(inb(0x60));
pic_eoi(1);
}
@ -115,6 +146,7 @@ static void __attribute__((interrupt)) irq_handler(void* r) {
void ps2kb_init(void) {
log_debug("init ps/2 keyboard...");
set_irq_handler(17, irq_handler);
unsigned status = inb(0x64);
if(status & 0xc0) {
@ -131,14 +163,13 @@ void ps2kb_init(void) {
command_byte(0x6);
command_byte(config | 1);
// flush output buffer
flush_output_buffer();
set_irq_handler(17, irq_handler);
pic_mask_irq(1, 0);
for(;;)
asm("hlt");
//log_debug("dzdvf");
while(1)
asm("hlt");
}

10
kernel/drivers/ps2kb.h

@ -4,6 +4,9 @@
void ps2kb_init(void);
// keys
#define PS2KB_ESCAPE 1
struct kbevent {
enum {
@ -16,4 +19,9 @@ struct kbevent {
typedef void (* kbevent_handler)(const struct kbevent* kbevent);
void ps2kb_set_event_callback(kbevent_handler h);
void ps2kb_set_event_callback(kbevent_handler h);
void ps2_trigger_CPU_reset(void);
// poll untill the specified key is pressed
void ps2kb_poll_wait_for_key(uint8_t key);

Loading…
Cancel
Save