Initial import of ViperOS
This commit is contained in:
134
VKernel/Kernel/drivers/input/mouse/mouse.py
Normal file
134
VKernel/Kernel/drivers/input/mouse/mouse.py
Normal file
@@ -0,0 +1,134 @@
|
||||
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")
|
||||
Reference in New Issue
Block a user