summaryrefslogtreecommitdiff
path: root/kernel/source
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-05-19 04:34:40 -0400
committerBenji Dial <benji@benjidial.net>2024-05-19 04:34:40 -0400
commite60fa7740cd7d245d1b22a25fea9df0768d32668 (patch)
tree728fa422d3a2abc66a3e2d89e4ef03b72074bb3e /kernel/source
parentb1a912a8a6ff472a49b2e0a09cfd433adfc2cb24 (diff)
downloadhilbert-os-e60fa7740cd7d245d1b22a25fea9df0768d32668.tar.gz
mouse support (working in qemu, semi-working in virtualbox)
Diffstat (limited to 'kernel/source')
-rw-r--r--kernel/source/input.cpp4
-rw-r--r--kernel/source/interrupts.asm102
-rw-r--r--kernel/source/interrupts.cpp49
-rw-r--r--kernel/source/syscall.cpp19
4 files changed, 152 insertions, 22 deletions
diff --git a/kernel/source/input.cpp b/kernel/source/input.cpp
index 696cb13..921ae7b 100644
--- a/kernel/source/input.cpp
+++ b/kernel/source/input.cpp
@@ -5,10 +5,10 @@
namespace hilbert::kernel::input {
- utility::queue<uint32_t> *key_queue;
+ utility::queue<input_packet> *input_queue;
void init_input() {
- key_queue = new utility::queue<uint32_t>();
+ input_queue = new utility::queue<input_packet>();
}
void got_input() {
diff --git a/kernel/source/interrupts.asm b/kernel/source/interrupts.asm
index babc020..e0c3cdb 100644
--- a/kernel/source/interrupts.asm
+++ b/kernel/source/interrupts.asm
@@ -227,14 +227,6 @@ section .bss
section .text
-write_keyboard_byte:
- in al, 0x64
- test al, 0x02
- jnz write_keyboard_byte
- mov al, dil
- out 0x60, al
- ret
-
extern on_keyboard_interrupt
keyboard_isr:
@@ -249,6 +241,7 @@ keyboard_isr:
push rcx
push rax
+ call wait_read_ps2
in al, 0x60
mov dil, al
@@ -269,6 +262,54 @@ keyboard_isr:
iretq
+extern on_mouse_interrupt
+
+mouse_isr:
+
+ push r11
+ push r10
+ push r9
+ push r8
+ push rsi
+ push rdi
+ push rdx
+ push rcx
+ push rax
+
+ call wait_read_ps2
+ in al, 0x60
+ mov dil, al
+
+ call on_mouse_interrupt
+
+ mov al, 0x20
+ out 0x20, al
+ out 0xa0, al
+
+ pop rax
+ pop rcx
+ pop rdx
+ pop rdi
+ pop rsi
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+
+ iretq
+
+wait_send_ps2:
+ in al, 0x64
+ test al, 0x02
+ jnz wait_send_ps2
+ ret
+
+wait_read_ps2:
+ in al, 0x64
+ test al, 0x01
+ jz wait_send_ps2
+ ret
+
load_gdt_and_idt:
;fill exception entries in idt
@@ -294,7 +335,7 @@ load_gdt_and_idt:
out 0x21, al
mov al, 0x01
out 0x21, al
- mov al, 0xfd ;mask all but irq 1
+ mov al, 0xf9 ;mask all but irq 1 and 2
out 0x21, al
mov al, 0x11
@@ -305,19 +346,54 @@ load_gdt_and_idt:
out 0xa1, al
mov al, 0x01
out 0xa1, al
- mov al, 0xff ;mask all
+ mov al, 0xef ;mask all but irq 12
out 0xa1, al
+ ;register keyboard and mouse interrupts
+
mov rdi, 0x21
mov rsi, keyboard_isr
call set_isr
- ;set keyboard config
+ mov rdi, 0x2c
+ mov rsi, mouse_isr
+ call set_isr
+
+ ;set ps2 config
+ call wait_send_ps2
mov al, 0x60
out 0x64, al
- mov dil, 0x01
- call write_keyboard_byte
+
+ call wait_send_ps2
+ mov al, 0x03
+ out 0x60, al
+
+ ;set mouse defaults
+
+ call wait_send_ps2
+ mov al, 0xd4
+ out 0x64, al
+
+ call wait_send_ps2
+ mov al, 0xf6
+ out 0x60, al
+
+ call wait_read_ps2
+ in al, 0x60
+
+ ;enable mouse reporting
+
+ call wait_send_ps2
+ mov al, 0xd4
+ out 0x64, al
+
+ call wait_send_ps2
+ mov al, 0xf4
+ out 0x60, al
+
+ call wait_read_ps2
+ in al, 0x60
;make tss entry in gdt
diff --git a/kernel/source/interrupts.cpp b/kernel/source/interrupts.cpp
index 6e22121..9b6495e 100644
--- a/kernel/source/interrupts.cpp
+++ b/kernel/source/interrupts.cpp
@@ -1,3 +1,4 @@
+#include <hilbert/kernel/framebuffer.hpp>
#include <hilbert/kernel/input.hpp>
#include <hilbert/kernel/panic.hpp>
@@ -54,7 +55,9 @@ static uint32_t current_flags = 0;
static void got_key(uint32_t key) {
- input::key_queue->insert(current_flags | key);
+ input::input_queue->insert({
+ .keyboard = current_flags | key, .is_mouse = false});
+
input::got_input();
if (key == (input::BREAK | 0x77))
@@ -90,7 +93,7 @@ static void got_key(uint32_t key) {
}
static uint8_t key_so_far[8];
-uint8_t key_so_far_len = 0;
+static uint8_t key_so_far_len = 0;
extern "C" void on_keyboard_interrupt(uint8_t byte) {
@@ -150,3 +153,45 @@ extern "C" void on_keyboard_interrupt(uint8_t byte) {
}
}
+
+static uint8_t mouse_packet_so_far[3];
+static uint8_t mouse_packet_so_far_len = 0;
+
+extern "C" void on_mouse_interrupt(uint8_t byte) {
+
+ if (mouse_packet_so_far_len == 0 && byte == 0xfa)
+ //dirty hack
+ return;
+
+ mouse_packet_so_far[mouse_packet_so_far_len++] = byte;
+ if (mouse_packet_so_far_len < 3)
+ return;
+
+ mouse_packet_so_far_len = 0;
+
+ int16_t x_change = mouse_packet_so_far[1];
+ int16_t y_change = -(int16_t)mouse_packet_so_far[2];
+ if (mouse_packet_so_far[0] & 0x10)
+ x_change -= 0x100;
+ if (mouse_packet_so_far[0] & 0x20)
+ y_change += 0x100;
+
+ input::input_packet packet = {
+ .mouse = {
+ .x_change = x_change, .y_change = y_change,
+ .buttons = (input::buttons_t)(mouse_packet_so_far[0] & 7) },
+ .is_mouse = true };
+
+ if (input::input_queue->count > 0 &&
+ input::input_queue->last_inserted().is_mouse &&
+ input::input_queue->last_inserted().mouse.buttons ==
+ packet.mouse.buttons) {
+ input::input_queue->last_inserted().mouse.x_change = packet.mouse.x_change;
+ input::input_queue->last_inserted().mouse.y_change = packet.mouse.y_change;
+ }
+ else
+ input::input_queue->insert(packet);
+
+ input::got_input();
+
+}
diff --git a/kernel/source/syscall.cpp b/kernel/source/syscall.cpp
index 768ff0d..5d9714c 100644
--- a/kernel/source/syscall.cpp
+++ b/kernel/source/syscall.cpp
@@ -157,7 +157,7 @@ namespace hilbert::kernel::syscall {
}
- void read_key_packet_syscall(
+ void get_input_packet_syscall(
uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx
) {
@@ -165,8 +165,17 @@ namespace hilbert::kernel::syscall {
auto *t = application::running_thread;
do
- if (input::key_queue->count > 0) {
- rax = (uint64_t)input::key_queue->take();
+ if (input::input_queue->count > 0) {
+ input::input_packet packet = input::input_queue->take();
+ if (packet.is_mouse) {
+ rax = packet.mouse.buttons | 0x80;
+ rdi = (uint16_t)packet.mouse.x_change;
+ rsi = (uint16_t)packet.mouse.y_change;
+ }
+ else {
+ rax = 0;
+ rdi = packet.keyboard;
+ }
return;
}
while (application::save_thread_state(t->cpu));
@@ -504,7 +513,7 @@ namespace hilbert::kernel::syscall {
&open_file_syscall,
&end_this_thread_syscall,
&get_new_pages_syscall,
- &read_key_packet_syscall,
+ &get_input_packet_syscall,
&create_private_socket_syscall,
&create_socket_listener_syscall,
&stop_socket_listener_syscall,
@@ -520,7 +529,7 @@ namespace hilbert::kernel::syscall {
&set_stream_length_syscall
};
- static constexpr int max_syscall_number = 18;
+ static constexpr int max_syscall_number = 19;
}