import asm import intr.idt as idt import platform.pch.pic as pic import drivers.serial.uart.serial as serial import t, c MOUSE_DATA: t.CDefine = 0x60 MOUSE_STATUS: t.CDefine = 0x64 MOUSE_COMMAND: t.CDefine = 0x64 MOUSE_BUF_SIZE: t.CDefine = 1024 MOUSE_LEFT: t.CDefine = 0x01 MOUSE_RIGHT: t.CDefine = 0x02 MOUSE_MIDDLE: t.CDefine = 0x04 class mouse_packet: flags: t.CUInt8T dx: t.CInt8T dy: t.CInt8T buttons: t.CUInt8T packets: t.CArray[mouse_packet, MOUSE_BUF_SIZE] pack_head: t.CStatic | t.CUInt32T = 0 pack_tail: t.CStatic | t.CUInt32T = 0 pack_count: t.CStatic | t.CUInt32T = 0 cycle: t.CStatic | t.CUInt8T = 0 byte1: t.CStatic | t.CUInt8T = 0 byte2: t.CStatic | t.CInt8T = 0 byte3: t.CStatic | t.CInt8T = 0 mouse_x: t.CStatic | t.CInt32T = 0 mouse_y: t.CStatic | t.CInt32T = 0 mouse_buttons: t.CStatic | t.CUInt8T = 0 def _wait_read(): timeout: t.CUInt32T = 100000 while timeout > 0: if (asm.inb(MOUSE_STATUS) & 0x01) != 0: return timeout -= 1 def _wait_write(): timeout: t.CUInt32T = 100000 while timeout > 0: if (asm.inb(MOUSE_STATUS) & 0x02) == 0: return timeout -= 1 def _write_cmd(cmd: t.CUInt8T): _wait_write() asm.outb(MOUSE_COMMAND, 0xD4) _wait_write() asm.outb(MOUSE_DATA, cmd) _wait_read() asm.inb(MOUSE_DATA) def irq_handler() -> t.CInt: global cycle, byte1, byte2, byte3, pack_tail, pack_count status: t.CUInt8T = asm.inb(MOUSE_STATUS) if (status & 0x20) == 0: return 0 data: t.CUInt8T = asm.inb(MOUSE_DATA) if cycle == 0: if (data & 0x08) != 0: byte1 = data cycle = 1 return 0 if cycle == 1: byte2 = data cycle = 2 return 0 byte3 = data cycle = 0 if pack_count < MOUSE_BUF_SIZE: packets[pack_tail].flags = byte1 packets[pack_tail].dx = byte2 packets[pack_tail].dy = byte3 packets[pack_tail].buttons = byte1 & t.CUInt8T(0x07) pack_tail = pack_tail + 1 if pack_tail >= MOUSE_BUF_SIZE: pack_tail = 0 pack_count += 1 return 0 def read_packet(out: mouse_packet | t.CPtr) -> t.CInt: global pack_head, pack_count asm.cli() if pack_count == 0: asm.sti() out.flags = 0 out.dx = 0 out.dy = 0 out.buttons = 0 return -1 out.flags = packets[pack_head].flags out.dx = packets[pack_head].dx out.dy = packets[pack_head].dy out.buttons = packets[pack_head].buttons pack_head = pack_head + 1 if pack_head >= MOUSE_BUF_SIZE: pack_head = 0 pack_count -= 1 asm.sti() return 0 def has_data() -> t.CInt: return pack_count def get_x() -> t.CInt32T: return mouse_x def get_y() -> t.CInt32T: return mouse_y def get_buttons() -> t.CUInt8T: return mouse_buttons def init(): _wait_write() asm.outb(MOUSE_COMMAND, 0xA8) _wait_write() asm.outb(MOUSE_COMMAND, 0x20) _wait_read() status: t.CUInt8T = asm.inb(MOUSE_DATA) status = status | 0x02 status = status & 0xDF _wait_write() asm.outb(MOUSE_COMMAND, 0x60) _wait_write() asm.outb(MOUSE_DATA, status) _write_cmd(0xF6) _write_cmd(0xF4) pic.clearMask(12) idt.irqInstallHandler(12, irq_handler, "mouse")