.{memory, buffer, log, string, math} := @use("../../../libraries/stn/src/lib.hb") Vec2 := math.Vec2 i9 := packed struct {sign: bool, value: u8} Button := struct {id: u8} LeftButton := Button.(1) RightButton := Button.(2) MiddleButton := Button.(4) Button4 := Button.(8) Button5 := Button.(16) mouse_moved := fn(delta: Vec2(i9)): void { log.info("Mouse movement.\0") } button_event := fn(button: Button, pressed: bool): void { if pressed { log.info("Mouse-button pressed.\0") } else { log.info("Mouse-button released.\0") } } send_byte := fn(target: u8, data: u8): void { loop if (memory.inb(0x64) & 2) == 0 break memory.outb(target, data) } reset_mouse := fn(): void { @inline(send_byte, 0x64, 0xD4) @inline(send_byte, 0x60, 0xFF) loop if memory.inb(0x60) == 0xAA { log.info("Self check passed.\0") return } } send_command_byte := fn(byte: u8): void { @inline(send_byte, 0x64, 0xD4) @inline(send_byte, 0x60, byte) loop if memory.inb(0x60) == 0xFA { log.info("ACK\0") return } } set_defaults := fn(): void @inline(send_command_byte, 0xF6) disable_streaming := fn(): void @inline(send_command_byte, 0xF5) enable_streaming := fn(): void @inline(send_command_byte, 0xF4) set_remote_mode := fn(): void @inline(send_command_byte, 0xF0) set_warp_mode := fn(): void @inline(send_command_byte, 0xEE) reset_warp_mode := fn(): void @inline(send_command_byte, 0xEC) set_stream_mode := fn(): void @inline(send_command_byte, 0xEA) set_non_linear_scaling := fn(): void @inline(send_command_byte, 0xE7) set_linear_scaling := fn(): void @inline(send_command_byte, 0xE6) resend_packet := fn(): void @inline(send_command_byte, 0xFE) SampleRate := struct {value: u8} sr10 := SampleRate.(10) sr20 := SampleRate.(20) sr40 := SampleRate.(40) sr60 := SampleRate.(60) sr80 := SampleRate.(80) sr100 := SampleRate.(100) sr200 := SampleRate.(200) set_sample_rate := fn(sample_rate: SampleRate): void { @inline(send_command_byte, 0xE6) @inline(send_command_byte, sample_rate.value) } Resolution := struct {value: u8} res_1count_per_mm := Resolution.(0) res_2count_per_mm := Resolution.(1) res_4count_per_mm := Resolution.(2) res_8count_per_mm := Resolution.(3) set_resolution := fn(resolution: Resolution): void { @inline(send_command_byte, 0xE6) @inline(send_command_byte, resolution.value) } button_states := @as(u8, 0) main := fn(): int { format_page := memory.alloc(u8, 1024) send_byte(0x64, 0xA8) log.info("Aux mouse device enabled.\0") reset_mouse() set_defaults() enable_streaming() x := @as(i16, 0) y := @as(i16, 0) loop { loop if (memory.inb(0x64) & 0x20) == 0x20 break status := memory.inb(0x60) if status == 0xAA { loop if memory.inb(0x60) == 0 break log.info("Mouse plugged in!\0") reset_mouse() set_defaults() enable_streaming() continue } changes := button_states ^ status & 7 if (changes & LeftButton.id) != 0 { button_event(LeftButton, (status & LeftButton.id) != 0) } if (changes & RightButton.id) != 0 { button_event(RightButton, (status & RightButton.id) != 0) } if (changes & MiddleButton.id) != 0 { button_event(MiddleButton, (status & MiddleButton.id) != 0) } button_states ^= changes log.info(string.display_int(status, format_page, 10)) dx := i9.(false, 0) dy := i9.(false, 0) dx.value = memory.inb(0x60) dx.sign = (status & 0x10) > 0 dy.value = memory.inb(0x60) ^ 0xFF dy.sign = (status & 0x20) == 0 if dy.value != 0 & dx.value != 0 { mouse_moved(.(dx, dy)) } } return 0 }