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

View file

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

View file

@ -1,4 +1,4 @@
; =============================================================================
80; =============================================================================
; Project : Custom BIOS / ROM
; File : gfx_cgam.asm
; Author : frater
@ -122,22 +122,22 @@ graph_driver:
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet
; ------------------------------------------------------------
cga_init:
mov ax, BDA_DATA_SEG
mov ds, ax
mov ax, BDA_DATA_SEG
mov ds, ax
; init graphics mode
mov ah, 0x00 ; AH=00h set video mode
mov al, GFX_MODE
int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
; init graphics mode
mov ah, 0x00 ; AH=00h set video mode
mov al, GFX_MODE
int 0x10
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved
mov byte [BDA_GFX + gfx.cur_mode], 1
; dessine un background "check-board"
call cga_background
ret
; mov byte [BDA_GFX + gfx.cur_mode], 1
; dessine un background "check-board"
call cga_background
ret
cga_none:
ret
ret
; ------------------------------------------------------------
@ -146,29 +146,29 @@ cga_none:
; Out: ES=VIDEO_SEG, DI=offset, AH=bitmask (0x80 >> (x&7))
; ------------------------------------------------------------
cga_calc_addr:
; calcul de l'offset 'y':
; si y est impaire, DI+=0x2000
; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000
mov ax, dx
shr ax, 1 ; ax = y/2
mov di, ax
shl di, 4 ; (y/2)*16
shl ax, 6 ; (y/2)*64
add di, ax ; *80
mov ax, cx
shr ax, 3
add di, ax
test dl, 1
jz .even
add di, CGA_ODD_BANK
; calcul de l'offset 'y':
; si y est impaire, DI+=0x2000
; DI = (y>>1)*80 + (x>>3) + (y&1)*0x2000
mov ax, dx
shr ax, 1 ; ax = y/2
mov di, ax
shl di, 4 ; (y/2)*16
shl ax, 6 ; (y/2)*64
add di, ax ; *80
mov ax, cx
shr ax, 3
add di, ax
test dl, 1
jz .even
add di, CGA_ODD_BANK
.even:
; masque bit = 0x80 >> (x&7)
push cx
and cl, 7
mov ah, 080h
shr ah, cl
pop cx
ret
; masque bit = 0x80 >> (x&7)
push cx
and cl, 7
mov ah, 080h
shr ah, cl
pop cx
ret
; ---------------------------------------------------------------------------
; gfx_set_charpos
@ -703,103 +703,64 @@ cga_cursor_draw:
mov ax, VIDEO_SEG
mov es, ax
; --- 1. CLIPPING VERTICAL ---
; --- CLIPPING VERTICAL ---
mov dx, [ds:BDA_MOUSE + mouse.y]
cmp dx, 200
jae .exit_total
mov bp, 16
mov ax, 200
sub ax, dx
sub ax, dx ; 200-y
cmp bp, ax
jbe .y_ok
jbe .y_ok ; y<= 200-16
mov bp, ax
.y_ok:
; --- 2. ADRESSAGE ---
mov cx, [ds:BDA_MOUSE + mouse.x]
mov dx, [ds:BDA_MOUSE + mouse.y]
call cga_calc_addr ; DI = Offset VRAM
; --- ADRESSAGE ---
mov cx, [BDA_MOUSE + mouse.x]
mov dx, [BDA_MOUSE + mouse.y]
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 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 dx, -0x2000 + 80 ; Retour + ligne suivante
test word [ds:BDA_MOUSE + mouse.y], 1
test word [BDA_MOUSE + mouse.y], 1
jz .setup_done
xchg bx, dx
neg bx
.setup_done:
and cx, 7 ; CL = Shift (0..7)
mov [BDA_MOUSE + mouse.cur_bank_add], bx ; interligne + ou - 0x2000
.row_loop:
; --- CONSTRUCTION DES MASQUES (EAX/EBX) ---
; On force l'ordre [GAUCHE][DROITE] visuel en lisant par octet
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
mov bx, [gs:si+32] ; Octet GAUCHE du masque XOR
;mov bh, [gs:si+33] ; Octet GAUCHE du masque XOR
;mov bl, [gs:si+32] ; Octet DROITE du masque XOR
shl ebx, 8 ; EBX = [00][GAUCHE][DROITE][00]
mov ax, [gs:si] ; masque AND
xchg al, ah
; 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) ---
; Octet 0 (Gauche)
mov dl, [es:di]
push eax
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
mov bx, [gs:si+32] ; masque XOR
xchg bl, bh
; expansion 16 bits -> 32 bits avec padding
;shl ebx, 8 ; EBX = [00][GAUCHE][DROITE][00]
; 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 ax, [ds:BDA_MOUSE + mouse.x]
shr ax, 3
cmp ax, 78
jae .next_line
mov dx, [es:di] ; lecture des 16 bits a la position du curseur
and dx, ax ; application du masque AND (AX)
xor dx, bx ; application du masque XOR (BX)
mov dl, [es:di+2]
and dl, al ; Bits 7-0
xor dl, bl
mov [es:di+2], dl
mov [es:di], dx ; ecriture du résultat
.next_line:
add di, bx
xchg bx, dx
add di, CGA_STRIDE
; [BDA_MOUSE + mouse.cur_bank_add]
add si, 2 ; Prochaine ligne du sprite
dec bp
jnz .row_loop

View file

@ -22,61 +22,47 @@
; =============================================================================
kbd_flush:
in al, 0x64 ; Lire le Status Register
test al, 1 ; Est-ce qu'il y a une donnée (Output Buffer Full) ?
jz .done
in al, 0x60 ; Lire et ignorer la donnée
jmp kbd_flush
in al, 0x64 ; Lire le Status Register
test al, 1 ; Est-ce qu'il y a une donnée (Output Buffer Full) ?
jz .done
in al, 0x60 ; Lire et ignorer la donnée
jmp kbd_flush
.done:
ret
ret
kbd_init:
push ds
push ax
push ds
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
mov ax, BDA_SEGMENT
mov ds, ax
mov byte [BDA_KBD_HEAD], 0
mov byte [BDA_KBD_TAIL], 0
mov byte [BDA_KBD_FLAGS], 0
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
; enable IRQ 1
mov ah,IRQ_ENABLED
mov al,1
call pic_set_irq_mask
pop ax
pop ds
ret
; -----------------------------------------------------------
; Keyboard ISR (IRQ -> INT)
; -----------------------------------------------------------
kbd_isr:
pusha
push ds
pusha
push ds
in al, 0x60 ; consomme scancode (obligatoire)
in al, 0x60 ; consomme scancode (obligatoire)
mov ax,BDA_DATA_SEG
mov ds,ax
inc byte [0x0000]
mov al, PIC_EOI ; EOI master
out i8259_MASTER_CMD, al
mov al, PIC_EOI ; EOI master
out i8259_MASTER_CMD, al
pop ds
popa
iret
pop ds
popa
iret

View file

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