# mouseInit 鼠标初始化器

`CODE/mouse` 生成早期鼠标初始化 ELF：

```text
CODE/mouse -> SYSTEM/system/deshab64/mouse/mouseInit.elf
```

## 目标

`mouseInit.elf` 是 DSK 直接调度的系统输入初始化器（首启链路：mouseInit → netman → FirstInit），初始化完成后返回 DSK，不驻留阻塞启动流程。任何单步失败只记日志继续执行，绝不阻塞或崩溃首次启动。

当前职责：

1. 完整初始化 PS/2 控制器 AUX 通道与鼠标：drain → 配置字节（bit5=0 / bit1=1 / bit6=1）→ 0xA8 → 0xFF 复位（drain ≤8 字节）→ 0xF6 Set Defaults → 0xF3 采样率 100 → 0xE8 分辨率 2 → 0xF4 启用数据报告，全程 100000 次超时保护并逐步验 ACK(0xFA)。
2. 实现 IRQ12 中断 handler + 3 字节包解码：同步位(bit3)校验重同步、9 位有符号位移合成（符号扩展）、溢出位丢包、Y 轴翻转、按 framebuffer 尺寸边界钳位。
3. 经 `kernel_api.irq_register` 注册 IRQ12 handler（仅注册，不解屏蔽 PIC、不 sti）。
4. 通过导出符号 `g_mouse_state` / `mouse_poll_state()` 暴露鼠标状态契约。
5. 输出串口日志并返回 DSK。

## 关键设计：handler 存活性与安全不变式

DSK 的 `dsk_load_elf` 把所有 DSK 调度模块（mouseInit/netman/FirstInit/login/desktop）加载进**同一块 1MB 静态镜像缓冲**：mouseInit 返回后，下一个模块加载即覆盖本镜像。因此 IRQ12 handler 与 `g_mouse_state` 只在 mouseInit 驻留期间有效。

本文件维持的安全不变式：

1. UTSM `pic_remap` 后从片 PIC 屏蔽字为 0xFF，IRQ12 保持屏蔽，本文件不解屏蔽；
2. DSK `dsk_entry` 已 `cli`，整个 DSK 阶段（含 desktop）IF=0，无任何模块 `sti`；

=> handler 已注册进内核 `g_irq_handlers[12]`，但永远不会被调用；镜像被覆盖后也不存在野指针执行风险。

后续集成路径（二选一，需本目录以外配套改动）：

- **DKM 输入驱动**：把解码逻辑搬进内核常驻 .drv（参照 ps2kbd），由它注册 IRQ12 并解屏蔽从片 bit4，desktop 改读共享状态；
- **DSK 常驻加载**：加载器增加"常驻"标志，mouseInit 镜像不被复用后，再解屏蔽 IRQ12。

## mouse_state_t 布局（ABI v1）

| 偏移 | 字段 | 类型 | 说明 |
| --- | --- | --- | --- |
| 0  | magic | u32 | `MOUSE_STATE_MAGIC`（"MOUS" 0x4D4F5553），消费者校验 |
| 4  | version | u32 | 布局版本，当前 1 |
| 8  | x | volatile i32 | 光标 X（边界钳位后） |
| 12 | y | volatile i32 | 光标 Y |
| 16 | buttons | volatile u32 | bit0=左键 bit1=右键 bit2=中键 |
| 20 | packet_count | volatile u32 | 成功解码包数 |
| 24 | overflow_count | volatile u32 | 溢出/失步丢弃计数 |
| 28 | max_x | i32 | 钳位右边界 = fb_width-1 |
| 32 | max_y | i32 | 钳位下边界 = fb_height-1 |

消费方式：校验 magic/version 后直接读 `g_mouse_state`，或调用 `mouse_poll_state(mouse_state_t *out)` 取得只读快照（返回 0 成功）。

## 与现有轮询消费者的兼容性

- FirstInit / desktop 均自带 PS/2 鼠标重新初始化（幂等）与 AUX 位感知轮询；mouseInit 启用数据报告后，它们照常读到鼠标包，互不干扰。
- 当前 handler 永不触发（PIC 屏蔽 + IF=0），不会吞掉轮询者的数据。
- 未来切换为 IRQ 驱动后，handler 会读走 0x60，desktop 必须同步切换为读共享状态而非轮询端口（见 main.c 顶部注释）。

## 当前限制

- handler/状态仅在 mouseInit 驻留期间有效；跨模块消费待 DKM 输入驱动或 DSK 常驻加载支持后落地。
- mouseInit 仅在首启链路被 DSK 调度；正常启动路径（login → desktop）由 desktop 自行初始化鼠标。
- USB 鼠标需要 xHCI/HID 支持，暂不在范围。

## 构建

```powershell
cd CODE\mouse
make -f MAKEFILE CC=clang LD=ld.lld
```

## 启动链路

```text
DSK 检测 firstInit=0
  -> 加载并调用 mouseInit.elf（初始化 + 注册 IRQ12 handler 后返回）
  -> netman.elf
  -> FirstInit.elf（用户设置向导，AUX 位感知轮询鼠标/键盘）
  -> desktop.elf（自带鼠标重初始化 + 轮询 + 光标局部重绘）
```
