cpu 8086 bits 16 org 0x7c00 mouse_packet equ 0x500 jmp 0:start start: cld cli ; Set up segments and stack mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, $$ ; Hook up IRQ12 mov [0x01D0], word mouse_irq mov [0x01D0 + 2], word 0 sti init_8042: ; TODO: This does not make sure the input buffer has been emptied ; before writing to it. Works fine in QEMU, but may fail on ; real hardware. ; Disable devices mov al, 0xad out 0x64, al mov al, 0xa7 out 0x64, al ; Flush output buffer in al, 0x60 ; Get controller config byte mov al, 0x20 out 0x64, al .wait_config: in al, 0x64 test al, 1<<0 ; Test whether output status buffer has data jz .wait_config in al, 0x60 ; Enable second PS/2 device (likely mouse) interrupt or al, 1<<1 mov bl, al mov al, 0x60 out 0x64, al mov al, bl out 0x60, al ; Enable devices mov al, 0xae out 0x64, al mov al, 0xa8 out 0x64, al init_mouse: ; Start packet streaming mov al, 0xd4 out 0x64, al mov al, 0xf4 out 0x60, al mainloop: ; TODO: everything hang: hlt jmp hang mouse_irq: push ax push bx ; Read mouse data in al, 0x60 xor bh, bh mov bl, [mouse_packet_fill] test bl, bl jnz .store_byte test al, 1<<3 ; Always-on bit in first byte jz .finish .store_byte: mov [mouse_packet + bx], al inc bl cmp bl, 3 jne .finish .full_packet: ; TODO: Do something useful with the mouse packet push si mov si, mouse_packet lodsb call hexprint8 lodsb call hexprint8 lodsb call hexprint8 pop si mov ax, 0x0e20 int 0x10 ; Empty out the mouse packet buffer xor bl, bl .finish: ; Store back possibly updated mouse packet fill mov [mouse_packet_fill], bl ; Reset PICs mov al, 0x20 out 0xa0, al out 0x20, al pop bx pop ax iret hexprint8: push ax push cx mov cl, 4 shr al, cl call hexprint4 pop cx pop ax hexprint4: push ax and al, 0xf cmp al, 10 jb .digit09 add al, 'a' - '0' - 10 .digit09: add al, '0' mov ah, 0x0e int 0x10 pop ax ret mouse_packet_fill db 0 times 510-($-$$) db 0 db 0x55 db 0xaa