summaryrefslogtreecommitdiff
path: root/Kernel/PS2MouseDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/PS2MouseDevice.cpp')
-rw-r--r--Kernel/PS2MouseDevice.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/Kernel/PS2MouseDevice.cpp b/Kernel/PS2MouseDevice.cpp
new file mode 100644
index 0000000000..c829c60539
--- /dev/null
+++ b/Kernel/PS2MouseDevice.cpp
@@ -0,0 +1,113 @@
+#include "PS2MouseDevice.h"
+#include "IO.h"
+
+PS2MouseDevice::PS2MouseDevice()
+ : IRQHandler(12)
+ , CharacterDevice(10, 1)
+{
+ initialize();
+}
+
+PS2MouseDevice::~PS2MouseDevice()
+{
+}
+
+void PS2MouseDevice::handle_irq()
+{
+ m_data[m_data_state] = IO::in8(0x60);
+ switch (m_data_state) {
+ case 0:
+ case 1:
+ ++m_data_state;
+ break;
+ case 2:
+ m_data_state = 0;
+ dbgprintf("PS2Mouse: %d, %d\n", m_data[1], m_data[2]);
+ break;
+ }
+}
+
+void PS2MouseDevice::wait_then_write(byte port, byte data)
+{
+ prepare_for_output();
+ IO::out8(port, data);
+}
+
+byte PS2MouseDevice::wait_then_read(byte port)
+{
+ prepare_for_input();
+ return IO::in8(port);
+}
+
+void PS2MouseDevice::initialize()
+{
+ // Enable PS aux port
+ wait_then_write(0x64, 0xa8);
+
+ // Enable interrupts
+ wait_then_write(0x64, 0x20);
+
+ byte status = wait_then_read(0x60) | 2;
+ wait_then_write(0x64, 0x60);
+ wait_then_write(0x60, status);
+
+ // Set default settings.
+ mouse_write(0xf6);
+ byte ack1 = mouse_read();
+ ASSERT(ack1 == 0xfa);
+
+ // Enable.
+ mouse_write(0xf4);
+ byte ack2 = mouse_read();
+ ASSERT(ack2 == 0xfa);
+
+ enable_irq();
+}
+
+void PS2MouseDevice::prepare_for_input()
+{
+ for (;;) {
+ if (IO::in8(0x64) & 1)
+ return;
+ }
+}
+
+void PS2MouseDevice::prepare_for_output()
+{
+ for (;;) {
+ if (!(IO::in8(0x64) & 2))
+ return;
+ }
+}
+
+void PS2MouseDevice::mouse_write(byte data)
+{
+ prepare_for_output();
+ IO::out8(0x64, 0xd4);
+ prepare_for_output();
+ IO::out8(0x60, data);
+}
+
+byte PS2MouseDevice::mouse_read()
+{
+ prepare_for_input();
+ return IO::in8(0x60);
+}
+
+bool PS2MouseDevice::has_data_available_for_reading() const
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+ssize_t PS2MouseDevice::read(byte* buffer, size_t buffer_size)
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+ssize_t PS2MouseDevice::write(const byte *buffer, size_t buffer_size)
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}