ableos/sysdata/programs/ps2_mouse_driver/src/main.hb

163 lines
3.8 KiB
Plaintext
Raw Normal View History

2024-11-03 16:48:36 -06:00
.{memory, buffer, log, string, math} := @use("../../../libraries/stn/src/lib.hb")
Vec2 := math.Vec2
2024-11-03 18:37:39 -06:00
render := @use("../../../libraries/render/src/lib.hb")
2024-11-03 16:48:36 -06:00
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)
}
2024-11-03 18:37:39 -06:00
set_up_mouse := fn(): void {
@inline(reset_mouse)
@inline(set_resolution, res_8count_per_mm)
@inline(enable_streaming)
}
2024-11-03 16:48:36 -06:00
button_states := @as(u8, 0)
main := fn(): int {
format_page := memory.alloc(u8, 1024)
2024-11-03 18:37:39 -06:00
screen := render.init(true)
// Clear the screen to black.
render.clear(screen, render.black)
2024-11-03 16:48:36 -06:00
send_byte(0x64, 0xA8)
log.info("Aux mouse device enabled.\0")
2024-11-03 18:37:39 -06:00
set_up_mouse()
set_resolution(res_8count_per_mm)
2024-11-03 16:48:36 -06:00
2024-11-03 18:37:39 -06:00
x := @as(u8, 0)
y := @as(u8, 0)
2024-11-03 16:48:36 -06:00
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")
2024-11-03 18:37:39 -06:00
set_up_mouse()
2024-11-03 16:48:36 -06:00
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
2024-11-03 18:37:39 -06:00
dy.value = -memory.inb(0x60)
2024-11-03 16:48:36 -06:00
dy.sign = (status & 0x20) == 0
if dy.value != 0 & dx.value != 0 {
mouse_moved(.(dx, dy))
2024-11-03 18:37:39 -06:00
x += dx.value
y += dy.value
2024-11-03 16:48:36 -06:00
}
2024-11-03 18:37:39 -06:00
render.clear(screen, render.black)
render.put_rect(screen, .(x, y), .(10, 10), render.white)
// Sync the screen
render.sync(screen)
2024-11-03 16:48:36 -06:00
}
return 0
}