Files
ViperOS/VKernel/Kernel/drivers/input/mouse/mouse.vp
T
TermiNexus a518f75b24 chore(vkernel): 重置基线 — 纳入 TPV codegen 修复配合的内核侧调整与既有工作区内容
- devfs.vp: string.split 传 PATH_BUFFER_SIZE(配合 split 新增容量参数)

- fat32_types.vp: lfn_extract 越界钳制(base+i > MAX_LFN 返回 -1)

- sheet.vp: gfx.Renderer 实参修正为 (fb, zb, w, h)(原单参导致 w/h=0 渲染空操作)

- 同批包含 VKernel 其余既有移植改动与 vpsdk/Apps/Libs 工作区内容
2026-09-11 14:27:01 +08:00

137 lines
3.4 KiB
Plaintext

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: uint8
dx: int8
dy: int8
buttons: uint8
packets: t.CArray[mouse_packet, MOUSE_BUF_SIZE]
pack_head: t.CStatic | uint32 = 0
pack_tail: t.CStatic | uint32 = 0
pack_count: t.CStatic | uint32 = 0
mse_irq_cnt: t.CStatic | uint64 = 0
cycle: t.CStatic | uint8 = 0
byte1: t.CStatic | uint8 = 0
byte2: t.CStatic | int8 = 0
byte3: t.CStatic | int8 = 0
mouse_x: t.CStatic | int32 = 0
mouse_y: t.CStatic | int32 = 0
mouse_buttons: t.CStatic | uint8 = 0
def _wait_read():
timeout: uint32 = 100000
while timeout > 0:
if (asm.inb(MOUSE_STATUS) & 0x01) != 0: return
timeout -= 1
def _wait_write():
timeout: uint32 = 100000
while timeout > 0:
if (asm.inb(MOUSE_STATUS) & 0x02) == 0: return
timeout -= 1
def _write_cmd(cmd: uint8):
_wait_write()
asm.outb(MOUSE_COMMAND, 0xD4)
_wait_write()
asm.outb(MOUSE_DATA, cmd)
_wait_read()
asm.inb(MOUSE_DATA)
def irq_handler() -> int:
global cycle, byte1, byte2, byte3, pack_tail, pack_count, mse_irq_cnt
mse_irq_cnt += 1
status: uint8 = asm.inb(MOUSE_STATUS)
if (status & 0x20) == 0: return 0
data: uint8 = 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 & uint8(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) -> int:
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() -> int:
return pack_count
def get_x() -> int32:
return mouse_x
def get_y() -> int32:
return mouse_y
def get_buttons() -> uint8:
return mouse_buttons
def init():
_wait_write()
asm.outb(MOUSE_COMMAND, 0xA8)
_wait_write()
asm.outb(MOUSE_COMMAND, 0x20)
_wait_read()
status: uint8 = 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")