bug fix init mouse + redraw cursor

This commit is contained in:
saintfrater 2026-01-28 14:22:19 +01:00
commit ab52449591
5 changed files with 348 additions and 397 deletions

View file

@ -55,27 +55,28 @@
%define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64 %define BKG_TOTAL_BYTES (BKG_TOTAL_DWORDS * 4) ; 64
struc mouse struc mouse
.buffer resb 4 ; i8042 input buffer .buffer resb 4 ; i8042 input buffer 0..3
.idx resb 1 ; index in the buffer .idx resb 1 ; index in the buffer 4
.packetlen resb 1 ; max buffer len (3 ou 4) .packetlen resb 1 ; max buffer len (3 ou 4) 5
.status resb 1 ; mouse status (button etc) .status resb 1 ; mouse status (button etc) 6
.wheel resb 1 ; if a packet size is 4; experimental .wheel resb 1 ; if a packet size is 4; experimental 7
.x resw 1 ; .x resw 1 ; 8..9
.y resw 1 .y resw 1 ; A..B
; cursor management ; cursor management
.cur_x resw 1 ; preservation des x,y du background .cur_x resw 1 ; preservation des x,y du background C..D
.cur_y resw 1 .cur_y resw 1 ; E..F
.cur_addr_start resw 1 ; adresse de départ de la sauvegarde .cur_addr_start resw 1 ; adresse de départ de la sauvegarde 10..11
.cur_bank_add resw 1 ; + ou - 0x2000 .cur_bank_add resw 1 ; + ou - 0x2000 12..13
.cur_drawing resb 1
.cur_visible resb 1 .cur_drawing resb 1 ; 14
.cur_seg resw 1 ; segment / offset of the pointer .cur_visible resb 1 ; 15
.cur_ofs resw 1 .cur_seg resw 1 ; segment / offset of the pointer 16..17
.cur_mask resb 1 ; pixels mask (bit per pixel) .cur_ofs resw 1 ; 18..19
.cur_bit_ofs resb 1 ; 0..7 bits d'offset (x&7) .cur_mask resb 1 ; pixels mask (bit per pixel) 1A
.bkg_saved resb 1 ; background saved .cur_bit_ofs resb 1 ; 0..7 bits d'offset (x&7) 1B
alignb 4 ; alignement 4 bytes .bkg_saved resb 1 ; background saved 1C
alignb 4 ; alignement 4 bytes 1D
.bkg_buffer resd 16 ; buffer for saved background .bkg_buffer resd 16 ; buffer for saved background
endstruc endstruc
@ -95,6 +96,8 @@ endstruc
%define BDA_MOUSE 0x0000 %define BDA_MOUSE 0x0000
%define BDA_GFX (BDA_MOUSE + mouse_size) %define BDA_GFX (BDA_MOUSE + mouse_size)
%warning offset Mouse: BAD_MOUSE, Gfx : BDA_GFX
; ;
; memory map ; memory map
; ;

View file

@ -31,8 +31,8 @@ bits 16
; initial stack ; initial stack
%define STACK_SEG 0x0800 ; segment de base %define STACK_SEG 0x0800 ; segment de base
section .text section .text
bits 16 bits 16
;%include "./common/chartable.asm" ;%include "./common/chartable.asm"
;%include "./common/cursor.asm" ;%include "./common/cursor.asm"

View file

@ -1,4 +1,4 @@
; ============================================================================= 80; =============================================================================
; Project : Custom BIOS / ROM ; Project : Custom BIOS / ROM
; File : gfx_cgam.asm ; File : gfx_cgam.asm
; Author : frater ; Author : frater
@ -122,22 +122,22 @@ graph_driver:
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet ; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_init: cga_init:
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
mov ds, ax mov ds, ax
; init graphics mode ; init graphics mode
mov ah, 0x00 ; AH=00h set video mode mov ah, 0x00 ; AH=00h set video mode
mov al, GFX_MODE mov al, GFX_MODE
int 0x10 int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
mov byte [BDA_GFX + gfx.cur_mode], 1 ; mov byte [BDA_GFX + gfx.cur_mode], 1
; dessine un background "check-board" ; dessine un background "check-board"
call cga_background call cga_background
ret ret
cga_none: cga_none:
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -146,29 +146,29 @@ cga_none:
; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7)) ; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7))
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_calc_addr: cga_calc_addr:
; calcul de l'offset 'y': ; calcul de l'offset 'y':
; si y est impaire, DI+=0x2000 ; si y est impaire, DI+=0x2000
; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000 ; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000
mov ax, dx mov ax, dx
shr ax, 1 ; ax = y/2 shr ax, 1 ; ax = y/2
mov di, ax mov di, ax
shl di, 4 ; (y/2)*16 shl di, 4 ; (y/2)*16
shl ax, 6 ; (y/2)*64 shl ax, 6 ; (y/2)*64
add di, ax ; *80 add di, ax ; *80
mov ax, cx mov ax, cx
shr ax, 3 shr ax, 3
add di, ax add di, ax
test dl, 1 test dl, 1
jz .even jz .even
add di, CGA_ODD_BANK add di, CGA_ODD_BANK
.even: .even:
; masque bit = 0x80 >> (x&7) ; masque bit = 0x80 >> (x&7)
push cx push cx
and cl, 7 and cl, 7
mov ah, 080h mov ah, 080h
shr ah, cl shr ah, cl
pop cx pop cx
ret ret
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; gfx_set_charpos ; gfx_set_charpos
@ -703,103 +703,64 @@ cga_cursor_draw:
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es, ax mov es, ax
; --- 1. CLIPPING VERTICAL --- ; --- CLIPPING VERTICAL ---
mov dx, [ds:BDA_MOUSE + mouse.y] mov dx, [ds:BDA_MOUSE + mouse.y]
cmp dx, 200 cmp dx, 200
jae .exit_total jae .exit_total
mov bp, 16 mov bp, 16
mov ax, 200 mov ax, 200
sub ax, dx sub ax, dx ; 200-y
cmp bp, ax cmp bp, ax
jbe .y_ok jbe .y_ok ; y<= 200-16
mov bp, ax mov bp, ax
.y_ok: .y_ok:
; --- 2. ADRESSAGE --- ; --- ADRESSAGE ---
mov cx, [ds:BDA_MOUSE + mouse.x] mov cx, [BDA_MOUSE + mouse.x]
mov dx, [ds:BDA_MOUSE + mouse.y] mov dx, [BDA_MOUSE + mouse.y]
call cga_calc_addr ; DI = Offset VRAM call cga_calc_addr ; DI = Offset VRAM
mov ax, [ds:BDA_MOUSE + mouse.cur_seg] mov ax, [BDA_MOUSE + mouse.cur_seg]
mov gs, ax mov gs, ax
mov si, [ds:BDA_MOUSE + mouse.cur_ofs] mov si, [BDA_MOUSE + mouse.cur_ofs]
; --- 3. CALCUL DES STRIDES --- ; --- CALCUL de l'offset entre 2 lignes +0x2000 ou -0x2000 ---
mov bx, 0x2000 ; Banque opposée mov bx, 0x2000 ; Banque opposée
mov dx, -0x2000 + 80 ; Retour + ligne suivante test word [BDA_MOUSE + mouse.y], 1
test word [ds:BDA_MOUSE + mouse.y], 1
jz .setup_done jz .setup_done
xchg bx, dx neg bx
.setup_done: .setup_done:
mov [BDA_MOUSE + mouse.cur_bank_add], bx ; interligne + ou - 0x2000
and cx, 7 ; CL = Shift (0..7)
.row_loop: .row_loop:
; --- CONSTRUCTION DES MASQUES (EAX/EBX) --- ; --- CONSTRUCTION DES MASQUES (EAX/EBX) ---
; On force l'ordre [GAUCHE][DROITE] visuel en lisant par octet
xor eax, eax xor eax, eax
;mov ah, [gs:si+1] ; Octet GAUCHE du masque AND
;mov al, [gs:si] ; Octet DROITE du masque AND
mov ax, [gs:si] ; Octet DROITE du masque AND
; Ton sprite cursor.asm utilise 0 pour le curseur, donc PAS de NOT
shl eax, 8
or eax, 0xFF0000FF ; Bourrage de 1 (fond transparent)
xor ebx, ebx xor ebx, ebx
mov bx, [gs:si+32] ; Octet GAUCHE du masque XOR
;mov bh, [gs:si+33] ; Octet GAUCHE du masque XOR mov ax, [gs:si] ; masque AND
;mov bl, [gs:si+32] ; Octet DROITE du masque XOR xchg al, ah
shl ebx, 8 ; EBX = [00][GAUCHE][DROITE][00] ; expansion 16 bits -> 32 bits avec padding
;shl eax, 8
;or eax, 0xFF0000FF ; EAX = [FF][GAUCHE][DROITE][FF]
; --- DECALAGE (SHIFT) ---
push edx
mov edx, 0xFFFFFFFF
shrd eax, edx, cl ; Injecte du fond (1) à gauche
xor edx, edx
shrd ebx, edx, cl ; Injecte du vide (0) à gauche
pop edx
; --- RMW SUR 3 OCTETS (Fenêtre de 24 bits) --- mov bx, [gs:si+32] ; masque XOR
; Octet 0 (Gauche) xchg bl, bh
mov dl, [es:di] ; expansion 16 bits -> 32 bits avec padding
push eax ;shl ebx, 8 ; EBX = [00][GAUCHE][DROITE][00]
shr eax, 16 ; Récupère bits 23-16
and dl, al
push ebx
shr ebx, 16
xor dl, bl
mov [es:di], dl
pop ebx
pop eax
; Octet 1 (Milieu)
mov dl, [es:di+1]
push eax
shr eax, 8
and dl, al ; Bits 15-8
push ebx
shr ebx, 8
xor dl, bl
mov [es:di+1], dl
pop ebx
pop eax
; Octet 2 (Droite + Clipping X) mov dx, [es:di] ; lecture des 16 bits a la position du curseur
mov ax, [ds:BDA_MOUSE + mouse.x] and dx, ax ; application du masque AND (AX)
shr ax, 3 xor dx, bx ; application du masque XOR (BX)
cmp ax, 78
jae .next_line
mov dl, [es:di+2] mov [es:di], dx ; ecriture du résultat
and dl, al ; Bits 7-0
xor dl, bl
mov [es:di+2], dl
.next_line: .next_line:
add di, bx add di, CGA_STRIDE
xchg bx, dx ; [BDA_MOUSE + mouse.cur_bank_add]
add si, 2 ; Prochaine ligne du sprite add si, 2 ; Prochaine ligne du sprite
dec bp dec bp
jnz .row_loop jnz .row_loop

View file

@ -22,61 +22,47 @@
; ============================================================================= ; =============================================================================
kbd_flush: kbd_flush:
in al, 0x64 ; Lire le Status Register in al, 0x64 ; Lire le Status Register
test al, 1 ; Est-ce qu'il y a une donnée (Output Buffer Full) ? test al, 1 ; Est-ce qu'il y a une donnée (Output Buffer Full) ?
jz .done jz .done
in al, 0x60 ; Lire et ignorer la donnée in al, 0x60 ; Lire et ignorer la donnée
jmp kbd_flush jmp kbd_flush
.done: .done:
ret ret
kbd_init: kbd_init:
push ds push ds
push ax push ax
call kbd_flush
; gestion du buffer clavier
call kbd_flush mov ax,cs ; get current CS
mov dx,ax
mov bx,kbd_isr ; Event handler
mov ax, i8259_MASTER_INT ; base offset IRQ 0
inc ax ; IRQ 1
call ivt_setvector
; gestion du buffer clavier ; enable IRQ 1
mov ax, BDA_SEGMENT mov ah,IRQ_ENABLED
mov ds, ax mov al,1
mov byte [BDA_KBD_HEAD], 0 call pic_set_irq_mask
mov byte [BDA_KBD_TAIL], 0 pop ax
mov byte [BDA_KBD_FLAGS], 0 pop ds
ret
mov ax,cs
mov dx,ax
mov bx,kbd_isr
mov ax, i8259_MASTER_INT ; base offset IRQ0
inc ax ; IRQ 1
call ivt_setvector
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al,1
call pic_set_irq_mask
pop ax
pop ds
ret
; ----------------------------------------------------------- ; -----------------------------------------------------------
; Keyboard ISR (IRQ -> INT) ; Keyboard ISR (IRQ -> INT)
; ----------------------------------------------------------- ; -----------------------------------------------------------
kbd_isr: kbd_isr:
pusha pusha
push ds push ds
in al, 0x60 ; consomme scancode (obligatoire) in al, 0x60 ; consomme scancode (obligatoire)
mov ax,BDA_DATA_SEG mov al, PIC_EOI ; EOI master
mov ds,ax out i8259_MASTER_CMD, al
inc byte [0x0000]
mov al, PIC_EOI ; EOI master pop ds
out i8259_MASTER_CMD, al popa
iret
pop ds
popa
iret

View file

@ -34,7 +34,7 @@
%define I8042_CMD_EN_AUX 0xA8 %define I8042_CMD_EN_AUX 0xA8
%define I8042_CMD_RD_CBYTE 0x20 %define I8042_CMD_RD_CBYTE 0x20
%define I8042_CMD_WR_CBYTE 0x60 %define I8042_CMD_WR_CBYTE 0x60
%define I8042_CMD_DIS_KBD 0xAD %define I8042_CMD_DIS_KBD 0xAD
%define I8042_CMD_DIS_MOUSE 0xA7 %define I8042_CMD_DIS_MOUSE 0xA7
%define I8042_CMD_WRITE_AUX 0xD4 %define I8042_CMD_WRITE_AUX 0xD4
@ -43,30 +43,30 @@
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_reset: mouse_reset:
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
mov fs,ax mov fs,ax
; effacer les variables du drivers ; effacer les variables du drivers
mov byte [fs:BDA_MOUSE + mouse.idx],0 mov byte [fs:BDA_MOUSE + mouse.idx],0
mov dword [fs:BDA_MOUSE + mouse.buffer],0 mov dword [fs:BDA_MOUSE + mouse.buffer],0
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
mov byte [fs:BDA_MOUSE + mouse.status],0 mov byte [fs:BDA_MOUSE + mouse.status],0
mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre mov word [fs:BDA_MOUSE + mouse.x],320 ; vous pouvez aussi préciser le centre
mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre mov word [fs:BDA_MOUSE + mouse.y],100 ; vous pouvez aussi préciser le centre
mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1 mov byte [fs:BDA_MOUSE + mouse.cur_visible], 1
mov word [fs:BDA_MOUSE + mouse.cur_x], 0 mov word [fs:BDA_MOUSE + mouse.cur_x], 0
mov word [fs:BDA_MOUSE + mouse.cur_y], 0 mov word [fs:BDA_MOUSE + mouse.cur_y], 0
mov byte [fs:BDA_MOUSE + mouse.cur_drawing], 0 mov byte [fs:BDA_MOUSE + mouse.cur_drawing], 0
mov ax, cs mov ax, cs
mov word [fs:BDA_MOUSE + mouse.cur_seg], ax mov word [fs:BDA_MOUSE + mouse.cur_seg], ax
mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow
; experiemntal ; experiemntal
mov word [fs:BDA_MOUSE + mouse.wheel],0 mov byte [fs:BDA_MOUSE + mouse.wheel],0
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; initialise le i8042 keyboard and mouse (PS/2) ; initialise le i8042 keyboard and mouse (PS/2)
@ -74,71 +74,72 @@ mouse_reset:
; on envoit les commandes RESET/DEFAULT/STREAM ; on envoit les commandes RESET/DEFAULT/STREAM
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_init: mouse_init:
push ds push ds
push ax push ax
; reset des valeurs internes ; reset des valeurs internes
call mouse_reset call mouse_reset
cli cli
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_DIS_KBD ; Disable Keyboard mov al, I8042_CMD_DIS_KBD ; Disable Keyboard
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_DIS_MOUSE ; Disable Mouse mov al, I8042_CMD_DIS_MOUSE ; Disable Mouse
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
; Vider tout ce qui traîne ; Vider tout ce qui traîne
call ps2_flush_output call ps2_flush_output
; Activer le port souris (AUX) ; Activer le port souris (AUX)
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_EN_AUX mov al, I8042_CMD_EN_AUX
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
; Lire command byte ; Lire command byte
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_RD_CBYTE mov al, I8042_CMD_RD_CBYTE
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
call ps2_read ; AL = command byte call ps2_read ; AL = command byte
; Activer IRQ12 (bit 1) ; Activer IRQ12 (bit 1)
or al, 02h or al, 02h
mov ah, al mov ah, al
; Réécrire command byte (commande 0x60 envoyée à 0x64) ; Réécrire command byte (commande 0x60 envoyée à 0x64)
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_WR_CBYTE mov al, I8042_CMD_WR_CBYTE
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, ah mov al, ah
out i8042_PS2_DATA, al out i8042_PS2_DATA, al
call ps2_flush_output call ps2_flush_output
; --- Reset ; --- Reset
; réponse attendue : 0xAA, [ID] ; réponse attendue : 0xAA, [ID]
mov bl, MOUSE_CMD_RESET mov bl, MOUSE_CMD_RESET
call mouse_sendcmd call mouse_sendcmd
call ps2_read ; 0xAA attendu (self-test OK) call ps2_read ; 0xAA attendu (self-test OK)
call ps2_read ; ID (souvent 0x00) call ps2_read ; ID (souvent 0x00)
; --- Default ; --- Default
mov bl, MOUSE_CMD_DEFAULT mov bl, MOUSE_CMD_DEFAULT
call mouse_sendcmd call mouse_sendcmd
; --- streaming ; --- streaming
mov bl, MOUSE_EN_STREAM mov bl, MOUSE_EN_STREAM
call mouse_sendcmd call mouse_sendcmd
; détecter le packet size (3/4 bytes)
call mouse_detect_packet_len
; installer ISR IRQ12 (INT 74h)
mov ax,cs
mov dx,ax
mov bx, isr_mouse_handler
mov ax, i8259_SLAVE_INT ; base offset IRQ8
add ax,4 ; IRQ 12
call ivt_setvector
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al, 12
call pic_set_irq_mask
sti
pop ax
pop ds
ret
; détecter le packet size (3/4 bytes)
call mouse_detect_packet_len
; installer ISR IRQ12 (INT 74h)
mov ax,cs
mov dx,ax
mov bx, isr_mouse_handler
mov ax, i8259_SLAVE_INT ; base offset IRQ8
add ax,4 ; IRQ 12
call ivt_setvector
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al, 12
call pic_set_irq_mask
sti
pop ax
pop ds
ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; detect la taille du "payload" de la souris. ; detect la taille du "payload" de la souris.
; ;
@ -146,42 +147,42 @@ mouse_init:
; ;
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_detect_packet_len: mouse_detect_packet_len:
mov ax, BDA_DATA_SEG mov ax, BDA_DATA_SEG
mov fs,ax mov fs,ax
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3 mov byte [fs:BDA_MOUSE + mouse.packetlen], 3
; SET_RATE + 200 ; SET_RATE + 200
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 200 mov bl, 200
call mouse_sendcmd call mouse_sendcmd
; SET_RATE + 100 ; SET_RATE + 100
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 100 mov bl, 100
call mouse_sendcmd call mouse_sendcmd
; SET_RATE + 80 ; SET_RATE + 80
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
call mouse_sendcmd call mouse_sendcmd
mov bl, 80 mov bl, 80
call mouse_sendcmd call mouse_sendcmd
; Get ID ; Get ID
mov bl, MOUSE_GET_ID mov bl, MOUSE_GET_ID
call mouse_sendcmd call mouse_sendcmd
call ps2_read ; AL = ID call ps2_read ; AL = ID
cmp al, 03h cmp al, 03h
je .is4 je .is4
cmp al, 04h cmp al, 04h
je .is4 je .is4
ret ret
.is4: .is4:
mov byte [fs:BDA_MOUSE + mouse.packetlen], 4 mov byte [fs:BDA_MOUSE + mouse.packetlen], 4
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; fonction de gestion du i8042 ; fonction de gestion du i8042
@ -190,41 +191,41 @@ mouse_detect_packet_len:
; attendre que le 8042 soit pret a recevoir de l'information ; attendre que le 8042 soit pret a recevoir de l'information
ps2_wait_ready_write: ps2_wait_ready_write:
push cx push cx
mov cx, 1000 mov cx, 1000
.wait: .wait:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 02h ; IBF test al, 02h ; IBF
jz .ok jz .ok
loop .wait loop .wait
.ok: .ok:
pop cx pop cx
ret ret
; attendre que le 8042 soit pret a lire de l'information ; attendre que le 8042 soit pret a lire de l'information
ps2_wait_ready_read: ps2_wait_ready_read:
.wait: .wait:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 01h ; OBF test al, 01h ; OBF
jz .wait jz .wait
ret ret
; lire de l'information depuis le 8042 ; lire de l'information depuis le 8042
ps2_read: ps2_read:
call ps2_wait_ready_read call ps2_wait_ready_read
in al, i8042_PS2_DATA in al, i8042_PS2_DATA
ret ret
; vide le buffer interne du 8042 (information(s) ignorée(s)) ; vide le buffer interne du 8042 (information(s) ignorée(s))
ps2_flush_output: ps2_flush_output:
.flush: .flush:
in al, i8042_PS2_CTRL in al, i8042_PS2_CTRL
test al, 01h test al, 01h
jz .done jz .done
in al, i8042_PS2_DATA in al, i8042_PS2_DATA
jmp .flush jmp .flush
.done: .done:
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; envoye une commande souris et attends le ACK ; envoye une commande souris et attends le ACK
@ -234,23 +235,23 @@ ps2_flush_output:
; renvoi CF=0 si ACK, CF=1 sinon ; renvoi CF=0 si ACK, CF=1 sinon
; ------------------------------------------------------------ ; ------------------------------------------------------------
mouse_sendcmd: mouse_sendcmd:
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, I8042_CMD_WRITE_AUX mov al, I8042_CMD_WRITE_AUX
out i8042_PS2_CTRL, al out i8042_PS2_CTRL, al
call ps2_wait_ready_write call ps2_wait_ready_write
mov al, bl mov al, bl
out i8042_PS2_DATA, al out i8042_PS2_DATA, al
call ps2_read ; AL = réponse call ps2_read ; AL = réponse
cmp al, MOUSE_ACK cmp al, MOUSE_ACK
jne .bad jne .bad
clc clc
ret ret
.bad: .bad:
stc stc
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
; interrupt handler ; interrupt handler
@ -271,76 +272,76 @@ mouse_sendcmd:
; bit 7 = Y overflow ; bit 7 = Y overflow
; ------------------------------------------------------------ ; ------------------------------------------------------------
isr_mouse_handler: isr_mouse_handler:
; sauvegarder tout les registres ; sauvegarder tout les registres
pusha pusha
push ds push ds
; use BDA segment ; use BDA segment
mov ax,BDA_DATA_SEG mov ax,BDA_DATA_SEG
mov ds,ax mov ds,ax
; lire un octet depuis le contrôleur et le stocker dans le buffer ; lire un octet depuis le contrôleur et le stocker dans le buffer
in al, i8042_PS2_DATA ; lire octet souris in al, i8042_PS2_DATA ; lire octet souris
movzx bx, byte [BDA_MOUSE + mouse.idx] movzx bx, byte [BDA_MOUSE + mouse.idx]
mov byte [BDA_MOUSE + mouse.buffer + bx], al mov byte [BDA_MOUSE + mouse.buffer + bx], al
inc byte [BDA_MOUSE + mouse.idx] inc byte [BDA_MOUSE + mouse.idx]
; vérifier si le packet est complet ; vérifier si le packet est complet
mov al, [BDA_MOUSE + mouse.packetlen] mov al, [BDA_MOUSE + mouse.packetlen]
cmp byte [BDA_MOUSE + mouse.idx], al cmp byte [BDA_MOUSE + mouse.idx], al
jb .done_eoi jb .done_eoi
; packet complet, on decode les données (ou on jette si c'est incorrect) ; packet complet, on decode les données (ou on jette si c'est incorrect)
mov byte [BDA_MOUSE + mouse.idx], 0 ; reset de l'index de lecture mov byte [BDA_MOUSE + mouse.idx], 0 ; reset de l'index de lecture
; check bit 3 octet 0 pour assurer que le bloc est ok: ; check bit 3 octet 0 pour assurer que le bloc est ok:
mov al, byte [BDA_MOUSE + mouse.buffer] mov al, byte [BDA_MOUSE + mouse.buffer]
and al, 00001000b ; bit 3 = 1 and al, 00001000b ; bit 3 = 1
je .done_eoi ; allignement erroné je .done_eoi ; allignement erroné
; debut du décodage des données ; debut du décodage des données
mov bl, [BDA_MOUSE + mouse.buffer] ; status mov bl, [BDA_MOUSE + mouse.buffer] ; status
mov al,bl mov al,bl
; --- BOUTONS (Optionnel mais recommandé) --- ; --- BOUTONS (Optionnel mais recommandé) ---
and al, 00000111b ; Bits 0, 1, 2 = Gauche, Droite, Milieu and al, 00000111b ; Bits 0, 1, 2 = Gauche, Droite, Milieu
mov [BDA_MOUSE + mouse.status], al mov [BDA_MOUSE + mouse.status], al
xor ax,ax xor ax,ax
mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X
test bl,00010000b ; signe X test bl,00010000b ; signe X
jz .x_pos jz .x_pos
mov ah,0xff ; X est négatif mov ah,0xff ; X est négatif
.x_pos: .x_pos:
add [BDA_MOUSE + mouse.x], ax add [BDA_MOUSE + mouse.x], ax
xor ax,ax xor ax,ax
mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y
test bl,00100000b ; signe Y test bl,00100000b ; signe Y
jz .y_pos jz .y_pos
mov ah,0xff ; y est négatif mov ah,0xff ; y est négatif
.y_pos: .y_pos:
sub [BDA_MOUSE + mouse.y], ax sub [BDA_MOUSE + mouse.y], ax
; check si il y a un 4eme byte a traiter ; check si il y a un 4eme byte a traiter
mov al, [BDA_MOUSE + mouse.packetlen] mov al, [BDA_MOUSE + mouse.packetlen]
cmp al,4 cmp al,4
jne .done_eoi jne .done_eoi
; si packetlen = 4, gérer la molette; experimental et non fonctionnel ; si packetlen = 4, gérer la molette; experimental et non fonctionnel
movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel movsx ax, byte [BDA_MOUSE + mouse.buffer+3] ; delta Wheel
add word [BDA_MOUSE + mouse.wheel], ax add word [BDA_MOUSE + mouse.wheel], ax
.done: .done:
; update la position du curseur sur l'écran ; update la position du curseur sur l'écran
; en ce moment c'est commented out (debug) ; en ce moment c'est commented out (debug)
; call gfx_cursor_move ; call gfx_cursor_move
.done_eoi: .done_eoi:
mov al, 0x20 mov al, 0x20
out i8259_SLAVE_CMD, al ; EOI PIC esclave out i8259_SLAVE_CMD, al ; EOI PIC esclave
out i8259_MASTER_CMD, al ; EOI PIC maître out i8259_MASTER_CMD, al ; EOI PIC maître
; restaurer tous les registres ; restaurer tous les registres
pop ds pop ds
popa popa
iret iret