vga Drivers +Mouse

This commit is contained in:
Frater 2026-02-16 19:45:13 +01:00
commit 7c9ad48b19
10 changed files with 730 additions and 404 deletions

200
src/boot-vga.asm Normal file
View file

@ -0,0 +1,200 @@
; =============================================================================
; Project : Custom BIOS / ROM
; File : boot.asm
; Author : frater
;
; License : GNU General Public License v3.0 or later (GPL-3.0+)
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
;
; =============================================================================
bits 16
; ---------------------------------------------------------------------------
;
; configuration du bios
;
; ---------------------------------------------------------------------------
; initial stack
%define STACK_SEG 0x0800 ; segment de base
%define GFX_DRIVERS 'VGA'
%define DEBUGER_ENABLED
section .text
bits 16
%include "./common/chartable.asm"
%include "./common/cursor.asm"
%include "./common/patterns.asm"
%include "./common/generic.asm"
%include "./common/string.asm"
; definition du BDA
%include "./common/bda.asm"
; drivers
%if GFX_DRIVERS == 'VGA'
%include "./drivers/gfx_vga.asm"
%else
; default drivers
%include "./drivers/gfx_cgam.asm"
%endif
%include "./drivers/mouse_ps2.asm"
%include "./drivers/keyboard_ps2.asm"
%include "./common/debug_gfx.asm"
%include "./common/debug_txt.asm"
; GUI
; %include "./gui/lib-api.asm"
; --- Données texte ---
str_quit db "Quitter", 0
str_hello db "Hello", 0
str_option1 db "option 1", 0
str_option2 db "option 2", 0
str_option3 db "option 3", 0
entrycode:
cli
mov ax, STACK_SEG ; creation du stack par défaut
mov ss, ax
mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné
cld
call ivt_setup ; configuration d'une table d'interruption "dummy"
call bda_setup ; initialisation du BDA
ISADBG ISA_GREEN, 1
; Install IRQ 0 : timer_isr
mov ax,cs
mov dx,ax
mov bx,timer_isr
mov ax,i8259_MASTER_INT
call ivt_setvector
; initialisation des PIC 8259A
call pic_init
; load Roms
call setup_load_rom
; on vérifie que le BIOS VGA a installé une INT 10h
call setup_check_vga
; enable IRQ 0
mov ah,IRQ_ENABLED
mov al,0
call pic_set_irq_mask
call kbd_init
sti
; on active le mode graphique
GFX INIT
call mouse_init
GFX MOUSE_SHOW
.loops:
call main_loop
jmp .loops
; --- Callbacks (Fonctions appelées par le moteur) ---
on_click_quit:
hlt
jmp on_click_quit
ret
on_click_hello:
ret
main_loop:
push bp
mov bp, sp
%define .oldval word [bp-2]
%define .my_slider word [bp-4]
%define .value word [bp-6]
sub sp, 6
push cs
pop ds
GFX GOTOXY, 5,5
GFX WRITE, str_hello
; Init du système GUI
; call gui_init_system
.loop:
; call gui_process_all
mov dh, 1
mov dl, 10
call scr_gotoxy
mov ax, BDA_CUSTOM_SEG
mov fs, ax
mov ax, word [fs:PTR_MOUSE + mouse.x]
call scr_puthex16
mov al, ' '
call scr_putc
mov ax, word [fs:PTR_MOUSE + mouse.y]
call scr_puthex16
nop
jmp .loop
leave
ret
; -----------------------------------------------------------
; timer ISR (IRQ -> INT)
; -----------------------------------------------------------
timer_isr:
push ax
push fs
mov ax,BDA_CUSTOM_SEG
mov fs,ax
; exemple de fonctionnement:
; inc byte [fs:BDA_TIMER]
mov al, PIC_EOI ; EOI master
out i8259_MASTER_CMD, al
pop fs
pop ax
iret
; ------------------------------------------------------------------
; Padding jusqu'au reset vector
; ------------------------------------------------------------------
times 0xFFF0 - ($ - $$) db 0xFF
; ------------------------------------------------------------------
; RESET VECTOR (exécuté par le CPU)
; ------------------------------------------------------------------
section .resetvect
bits 16
global reset_vector
reset_vector:
; code minimal au reset
jmp 0xF000:entrycode
builddate:
db __DATE__
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)

View file

@ -19,178 +19,4 @@
; along with this program. If not, see <https://www.gnu.org/licenses/>. ; along with this program. If not, see <https://www.gnu.org/licenses/>.
; ;
; ============================================================================= ; =============================================================================
%include "./boot-vga.asm"
bits 16
; ---------------------------------------------------------------------------
;
; configuration du bios
;
; ---------------------------------------------------------------------------
; initial stack
%define STACK_SEG 0x0800 ; segment de base
%define GFX_DRIVERS 'VGA'
%define DEBUGER_ENABLED
section .text
bits 16
%include "./common/chartable.asm"
%include "./common/cursor.asm"
%include "./common/patterns.asm"
%include "./common/generic.asm"
%include "./common/string.asm"
; definition du BDA
%include "./common/bda.asm"
; drivers
%if GFX_DRIVERS == 'VGA'
%include "./drivers/gfx_vga.asm"
%else
; default drivers
%include "./drivers/gfx_cgam.asm"
%endif
%include "./drivers/mouse_ps2.asm"
%include "./drivers/keyboard_ps2.asm"
%include "./common/debug_gfx.asm"
; GUI
; %include "./gui/lib-api.asm"
; --- Données texte ---
str_quit db "Quitter", 0
str_hello db "Hello", 0
str_option1 db "option 1", 0
str_option2 db "option 2", 0
str_option3 db "option 3", 0
entrycode:
cli
mov ax, STACK_SEG ; creation du stack par défaut
mov ss, ax
mov sp, 0xFFFE ; haut du segment (64ko de stack), mot-aligné
cld
call ivt_setup ; configuration d'une table d'interruption "dummy"
call bda_setup ; initialisation du BDA
ISADBG ISA_GREEN, 1
; Install IRQ 0 : timer_isr
mov ax,cs
mov dx,ax
mov bx,timer_isr
mov ax,i8259_MASTER_INT
call ivt_setvector
; initialisation des PIC 8259A
call pic_init
; load Roms
call setup_load_rom
; on vérifie que le BIOS VGA a installé une INT 10h
call setup_check_vga
; enable IRQ 0
mov ah,IRQ_ENABLED
mov al,0
call pic_set_irq_mask
call kbd_init
sti
ISADBG ISA_GREEN, 32
; on active le mode graphique
GFX INIT
call mouse_reset
; call mouse_init
GFX MOUSE_MOVE
ISADBG ISA_RED, 0x80
GFX MOUSE_SHOW
ISADBG ISA_RED, 0x81
.loops:
call main_loop
jmp .loops
; --- Callbacks (Fonctions appelées par le moteur) ---
on_click_quit:
hlt
jmp on_click_quit
ret
on_click_hello:
ret
%define .oldval word [bp-2]
%define .my_slider word [bp-4]
%define .value word [bp-6]
main_loop:
push bp
mov bp, sp
sub sp, 6
push cs
pop ds
DEBUG 1
ISADBG ISA_LEFT, 1
; Init du système GUI
; call gui_init_system
DEBUG 2
ISADBG ISA_LEFT, 2
.loop:
; call gui_process_all
jmp .loop
leave
ret
; -----------------------------------------------------------
; timer ISR (IRQ -> INT)
; -----------------------------------------------------------
timer_isr:
push ax
push fs
mov ax,BDA_CUSTOM_SEG
mov fs,ax
; exemple de fonctionnement:
; inc byte [fs:BDA_TIMER]
mov al, PIC_EOI ; EOI master
out i8259_MASTER_CMD, al
pop fs
pop ax
iret
; ------------------------------------------------------------------
; Padding jusqu'au reset vector
; ------------------------------------------------------------------
times 0xFFF0 - ($ - $$) db 0xFF
; ------------------------------------------------------------------
; RESET VECTOR (exécuté par le CPU)
; ------------------------------------------------------------------
section .resetvect
bits 16
global reset_vector
reset_vector:
; code minimal au reset
jmp 0xF000:entrycode
builddate:
db __DATE__
times 16-($-$$) db 0 ; le stub tient dans 16 octets (ou moins)

View file

@ -28,6 +28,9 @@
%define BDA_CUSTOM_SEG 0x0050 ; custom data (mouse, gfx cursor, etc..) %define BDA_CUSTOM_SEG 0x0050 ; custom data (mouse, gfx cursor, etc..)
%define BDA_GUI_WIDGET 0x0070 ; Segment de données UI (Safe: après Stack, avant Heap) %define BDA_GUI_WIDGET 0x0070 ; Segment de données UI (Safe: après Stack, avant Heap)
%define PTR_MOUSE 0x0000
%define PTR_GFX (PTR_MOUSE + mouse_size)
; video related information (compatible with VGA bios) ; video related information (compatible with VGA bios)
%define BDA_VIDEO_CURR_MODE 0x0049 %define BDA_VIDEO_CURR_MODE 0x0049
%define BDA_VIDEO_COLUMNS 0x004A %define BDA_VIDEO_COLUMNS 0x004A
@ -37,7 +40,7 @@
; information relative à la souris ; information relative à la souris
; ;
%define BDA_BitPP 4 %define BDA_BitPPixel 4
%define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne %define BKG_DWORDS_PER_LINE 1 ; 1 dword stocké par ligne
%define BKG_LINES 16 %define BKG_LINES 16
@ -45,55 +48,52 @@
%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
.idx resb 1 ; index in the buffer .idx resb 1 ; index in the buffer
.packetlen resb 1 ; max buffer len (3 ou 4) .packetlen resb 1 ; max buffer len (3 ou 4)
.status resb 1 ; mouse status (button etc) .status resb 1 ; mouse status (button etc)
.wheel resb 1 ; if a packet size is 4; experimental .wheel resb 1 ; if a packet size is 4; experimental
.x resw 1 ; .x resw 1 ;
.y resw 1 ; .y resw 1 ;
; cursor management ; cursor management
.cur_x resw 1 ; preservation des x,y du background .cur_x resw 1 ; preservation des x,y du background
.cur_y resw 1 ; .cur_y resw 1 ;
.cur_addr_start resw 1 ; adresse de départ de la sauvegarde .cur_addr_start resw 1 ; adresse de départ de la sauvegarde
.cur_drawing resb 1 ; .cur_drawing resb 1 ;
.cur_counter resb 1 ; compteur de fois que le curseur a été caché (0 = visible, <0 = invisible) .cur_counter resb 1 ; compteur de fois que le curseur a été caché (0 = visible, <0 = invisible)
.cur_seg resw 1 ; segment / offset of the pointer .cur_seg resw 1 ; segment / offset of the pointer
.cur_ofs resw 1 ; .cur_ofs resw 1 ;
.bkg_saved resb 1 ; background saved .bkg_saved resb 1 ; background saved
alignb 4 ; alignement 4 bytes alignb 4 ; alignement 4 bytes
; buffer for saved background ; buffer for saved background
.bkg_buffer resd 16*BDA_BitPP .bkg_buffer resd 16*BDA_BitPPixel
endstruc endstruc
struc gfx struc gfx
.cur_x resw 1 ; x,y en pixel .cur_x resw 1 ; x,y en pixel
.cur_y resw 1 .cur_y resw 1
.cur_offset resw 1 ; offset calculé pour le prochain caractère .cur_offset resw 1 ; offset calculé pour le prochain caractère
.cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h .cur_line_ofs resw 1 ; "interligne" +2000h ou -2000h
.cur_shift resb 1 ; x&7 (0..7) .cur_shift resb 1 ; x&7 (0..7)
.cur_mode resb 1 ; .cur_mode resb 1 ;
endstruc endstruc
%define BDA_MOUSE 0x0000
%define BDA_GFX (BDA_MOUSE + mouse_size)
; ----------------------------------------------------------------------------------- ; -----------------------------------------------------------------------------------
; bda_setup ; bda_setup
; Initialise la BDA à zéro ; Initialise la BDA à zéro
; ----------------------------------------------------------------------------------- ; -----------------------------------------------------------------------------------
bda_setup: bda_setup:
pusha pusha
push ds push ds
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov es, ax mov es, ax
mov ax, 0x5F mov ax, 0x5F
mov cx,0xFF mov cx,0xFF
xor di, di xor di, di
rep stosb ; clear BDA area rep stosb ; clear BDA area
pop ds pop ds
popa popa
ret ret

View file

@ -21,6 +21,7 @@ mouse_arrow:
dw 1111110000111111b ; 0xFC3F dw 1111110000111111b ; 0xFC3F
dw 1111111000111111b ; 0xFE3F dw 1111111000111111b ; 0xFE3F
dw 0000000000000000b ; 0x0000 dw 0000000000000000b ; 0x0000
dw 0010000000000000b ; 0x2000 dw 0010000000000000b ; 0x2000
dw 0011000000000000b ; 0x3000 dw 0011000000000000b ; 0x3000
dw 0011100000000000b ; 0x3800 dw 0011100000000000b ; 0x3800

View file

@ -23,7 +23,7 @@
%define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9 %define DEBUG_PORT 0xe9 ; 0x402 ou 0xe9
debug_puts: debug_puts:
.next: .next:
push dx push dx
mov dx, DEBUG_PORT mov dx, DEBUG_PORT
lodsb ; AL = *SI++ lodsb ; AL = *SI++
@ -31,7 +31,7 @@ debug_puts:
jz .done jz .done
out dx, al out dx, al
jmp .next jmp .next
.done: .done:
pop dx pop dx
ret ret
@ -49,9 +49,9 @@ debug_puthex4:
jbe .num jbe .num
add al, 'A' - 10 add al, 'A' - 10
jmp .pout jmp .pout
.num: .num:
add al, '0' add al, '0'
.pout: .pout:
call debug_putc call debug_putc
ret ret
@ -88,6 +88,8 @@ scr_gotoxy:
scr_putc: scr_putc:
mov ah, 0x0E mov ah, 0x0E
mov bh, 0x00
mov bl, 0x0f
int 10h int 10h
ret ret
@ -98,12 +100,14 @@ scr_puthex4:
jbe .num ; yes jbe .num ; yes
add al, 'A' - 10 ; convert to 'A'..'F' add al, 'A' - 10 ; convert to 'A'..'F'
jmp .pout jmp .pout
.num: .num:
add al, '0' ; convert to '0'..'9' add al, '0' ; convert to '0'..'9'
.pout: .pout:
mov ah, 0x0E mov ah, 0x0e
mov bh, 0x00
mov bl, 0x0f
int 10h int 10h
ret ret
; AL = byte -> print 2 hex digits ; AL = byte -> print 2 hex digits
scr_puthex8: scr_puthex8:

View file

@ -172,13 +172,12 @@ cga_calc_addr:
; si le mode n'est pas transparent, la couleur de fond ; si le mode n'est pas transparent, la couleur de fond
; est l'inverse de la couleur du texte ; est l'inverse de la couleur du texte
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; --- Définition des arguments ---
%define .mode word [bp+4]
cga_set_writemode: cga_set_writemode:
push bp push bp
mov bp, sp mov bp, sp
; --- Définition des arguments ---
%define .mode word [bp+4]
push fs push fs
push ax push ax
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
@ -186,12 +185,13 @@ cga_set_writemode:
mov ax, .mode mov ax, .mode
mov byte [fs:BDA_GFX + gfx.cur_mode], al mov byte [fs:PTR_GFX + gfx.cur_mode], al
pop ax pop ax
pop fs pop fs
leave leave
ret ret
%undef .mode
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; gfx_set_charpos (x,y) ; gfx_set_charpos (x,y)
@ -219,12 +219,12 @@ cga_set_charpos:
mov cx, .x mov cx, .x
mov dx, .y mov dx, .y
mov [fs:BDA_GFX + gfx.cur_x], cx mov [fs:PTR_GFX + gfx.cur_x], cx
mov [fs:BDA_GFX + gfx.cur_y], dx mov [fs:PTR_GFX + gfx.cur_y], dx
mov ax, cx mov ax, cx
and ax, 0x07 and ax, 0x07
mov [fs:BDA_GFX + gfx.cur_shift], al mov [fs:PTR_GFX + gfx.cur_shift], al
; calcul de l'offset de la position 'x,y': ; calcul de l'offset de la position 'x,y':
; si 'y' est paire, DI < 0x2000 & add = 0x2000 ; si 'y' est paire, DI < 0x2000 & add = 0x2000
@ -247,8 +247,8 @@ cga_set_charpos:
neg ax neg ax
add ax, CGA_STRIDE add ax, CGA_STRIDE
.even: .even:
mov [fs:BDA_GFX + gfx.cur_line_ofs], ax mov [fs:PTR_GFX + gfx.cur_line_ofs], ax
mov [fs:BDA_GFX + gfx.cur_offset], bx mov [fs:PTR_GFX + gfx.cur_offset], bx
pop fs pop fs
@ -323,10 +323,10 @@ cga_putc:
call get_glyph_offset call get_glyph_offset
; Base offset VRAM pour la scanline Y ; Base offset VRAM pour la scanline Y
mov di, [fs:BDA_GFX + gfx.cur_offset] mov di, [fs:PTR_GFX + gfx.cur_offset]
mov bx, [fs:BDA_GFX + gfx.cur_line_ofs] mov bx, [fs:PTR_GFX + gfx.cur_line_ofs]
mov ch, [fs:BDA_GFX + gfx.cur_mode] mov ch, [fs:PTR_GFX + gfx.cur_mode]
mov cl, [fs:BDA_GFX + gfx.cur_shift] mov cl, [fs:PTR_GFX + gfx.cur_shift]
mov .cpt, 4 mov .cpt, 4
@ -391,8 +391,8 @@ cga_putc:
jnz .row_loop jnz .row_loop
; Avancer curseur d'un caractère (8 pixels) ; Avancer curseur d'un caractère (8 pixels)
inc word [fs:BDA_GFX + gfx.cur_offset] inc word [fs:PTR_GFX + gfx.cur_offset]
add word [fs:BDA_GFX + gfx.cur_x], 8 add word [fs:PTR_GFX + gfx.cur_x], 8
call cga_mouse_show ; Restauration souris call cga_mouse_show ; Restauration souris
@ -1272,10 +1272,10 @@ cga_mouse_hide:
mov ds, ax mov ds, ax
; Décrémenter le compteur ; Décrémenter le compteur
dec byte [BDA_MOUSE + mouse.cur_counter] dec byte [PTR_MOUSE + mouse.cur_counter]
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1) ; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
cmp byte [BDA_MOUSE + mouse.cur_counter], -1 cmp byte [PTR_MOUSE + mouse.cur_counter], -1
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
call cga_cursor_restorebg call cga_cursor_restorebg
@ -1300,10 +1300,10 @@ cga_mouse_show:
mov ds, ax mov ds, ax
; Incrémenter le compteur ; Incrémenter le compteur
inc byte [BDA_MOUSE + mouse.cur_counter] inc byte [PTR_MOUSE + mouse.cur_counter]
; Vérifier si on est revenu à 0 (Visible) ; Vérifier si on est revenu à 0 (Visible)
cmp byte [BDA_MOUSE + mouse.cur_counter], 0 cmp byte [PTR_MOUSE + mouse.cur_counter], 0
jne .skip_draw ; Si on est encore à -1, -2... on reste caché jne .skip_draw ; Si on est encore à -1, -2... on reste caché
; C'est la transition Caché -> Visible : On affiche le curseur ; C'est la transition Caché -> Visible : On affiche le curseur
@ -1331,13 +1331,13 @@ cga_mouse_cursor_move:
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov ds, ax mov ds, ax
cmp byte [BDA_MOUSE + mouse.cur_counter], 0 cmp byte [PTR_MOUSE + mouse.cur_counter], 0
jl .done ; Si < 0, on ne dessine rien ! jl .done ; Si < 0, on ne dessine rien !
cmp byte [BDA_MOUSE + mouse.cur_drawing],0 cmp byte [PTR_MOUSE + mouse.cur_drawing],0
jne .done jne .done
mov byte [BDA_MOUSE + mouse.cur_drawing],1 mov byte [PTR_MOUSE + mouse.cur_drawing],1
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es, ax mov es, ax
@ -1347,7 +1347,7 @@ cga_mouse_cursor_move:
call cga_cursor_savebg call cga_cursor_savebg
call cga_cursor_draw call cga_cursor_draw
mov byte [BDA_MOUSE + mouse.cur_drawing],0 mov byte [PTR_MOUSE + mouse.cur_drawing],0
.done: .done:
pop es pop es
pop ds pop ds
@ -1360,7 +1360,7 @@ cga_mouse_cursor_move:
; Stocke 16 DWORDs: chaque DWORD contient les 4 bytes de la ligne ; Stocke 16 DWORDs: chaque DWORD contient les 4 bytes de la ligne
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_cursor_savebg: cga_cursor_savebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré cmp byte [PTR_MOUSE + mouse.bkg_saved], 0 ; le buffer n'a pas encore été restauré
jne .done jne .done
push es push es
@ -1368,16 +1368,16 @@ cga_cursor_savebg:
mov es, ax mov es, ax
; mémoriser position courante (utilisée pour restore) ; mémoriser position courante (utilisée pour restore)
mov cx, [BDA_MOUSE + mouse.x] mov cx, [PTR_MOUSE + mouse.x]
mov dx, [BDA_MOUSE + mouse.y] mov dx, [PTR_MOUSE + mouse.y]
mov [BDA_MOUSE + mouse.cur_x], cx mov [PTR_MOUSE + mouse.cur_x], cx
mov [BDA_MOUSE + mouse.cur_y], dx mov [PTR_MOUSE + mouse.cur_y], dx
; calcule ES:DI pour (x,y) ; calcule ES:DI pour (x,y)
call cga_calc_addr call cga_calc_addr
mov [BDA_MOUSE + mouse.cur_addr_start], di mov [PTR_MOUSE + mouse.cur_addr_start], di
lea si, [BDA_MOUSE + mouse.bkg_buffer] lea si, [PTR_MOUSE + mouse.bkg_buffer]
mov cx,16 mov cx,16
@ -1398,7 +1398,7 @@ cga_cursor_savebg:
pop es pop es
.done: .done:
mov byte [BDA_MOUSE + mouse.bkg_saved], 1 ; Flag mis à jour après la copie mov byte [PTR_MOUSE + mouse.bkg_saved], 1 ; Flag mis à jour après la copie
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -1406,7 +1406,7 @@ cga_cursor_savebg:
; Restaure 16 lignes sauvegardées. ; Restaure 16 lignes sauvegardées.
; ------------------------------------------------------------ ; ------------------------------------------------------------
cga_cursor_restorebg: cga_cursor_restorebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
je .done je .done
push es push es
@ -1414,8 +1414,8 @@ cga_cursor_restorebg:
mov es, ax mov es, ax
; restaurer depuis la dernière position sauvegardée ; restaurer depuis la dernière position sauvegardée
mov di, [BDA_MOUSE + mouse.cur_addr_start] mov di, [PTR_MOUSE + mouse.cur_addr_start]
lea si, [BDA_MOUSE + mouse.bkg_buffer] lea si, [PTR_MOUSE + mouse.bkg_buffer]
mov cx, 16 mov cx, 16
.row_loop: .row_loop:
@ -1434,18 +1434,20 @@ cga_cursor_restorebg:
pop es pop es
.done: .done:
mov byte [BDA_MOUSE + mouse.bkg_saved], 0 ; Flag mis à jour après la restauration mov byte [PTR_MOUSE + mouse.bkg_saved], 0 ; Flag mis à jour après la restauration
ret ret
; ============================================================ ; ============================================================
; cga_cursor_draw ; cga_cursor_draw
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA) ; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
; ============================================================ ; ============================================================
%define .height word [bp-2]
%define .mask dword [bp-6]
cga_cursor_draw: cga_cursor_draw:
push bp push bp
mov bp, sp mov bp, sp
; variables
%define .height word [bp-2]
%define .mask dword [bp-6]
sub sp, 6 ; Reserve space for locals sub sp, 6 ; Reserve space for locals
pushad pushad
@ -1460,7 +1462,7 @@ cga_cursor_draw:
mov es, ax mov es, ax
; --- CLIPPING VERTICAL --- ; --- CLIPPING VERTICAL ---
mov dx, [ds:BDA_MOUSE + mouse.y] mov dx, [ds:PTR_MOUSE + mouse.y]
mov bx, GFX_HEIGHT mov bx, GFX_HEIGHT
cmp dx, bx cmp dx, bx
jae .exit_total jae .exit_total
@ -1478,7 +1480,7 @@ cga_cursor_draw:
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79). ; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
; Si StartByte >= 77, on déborde. ; Si StartByte >= 77, on déborde.
mov cx, [BDA_MOUSE + mouse.x] mov cx, [PTR_MOUSE + mouse.x]
shr cx, 3 ; CX = Byte Offset (0-79) shr cx, 3 ; CX = Byte Offset (0-79)
xor esi, esi ; ESI = Masque de protection (0 = tout dessiner) xor esi, esi ; ESI = Masque de protection (0 = tout dessiner)
@ -1508,17 +1510,17 @@ cga_cursor_draw:
mov .mask, esi mov .mask, esi
; --- ADRESSAGE --- ; --- ADRESSAGE ---
mov cx, [BDA_MOUSE + mouse.x] mov cx, [PTR_MOUSE + mouse.x]
mov dx, [BDA_MOUSE + mouse.y] mov dx, [PTR_MOUSE + mouse.y]
call cga_calc_addr ; DI = Offset VRAM call cga_calc_addr ; DI = Offset VRAM
mov ax, [BDA_MOUSE + mouse.cur_seg] mov ax, [PTR_MOUSE + mouse.cur_seg]
mov gs, ax mov gs, ax
mov si, [BDA_MOUSE + mouse.cur_ofs] mov si, [PTR_MOUSE + mouse.cur_ofs]
; --- CALCUL de l'offset entre 2 lignes +0x2000 ou -0x2000 --- ; --- CALCUL de l'offset entre 2 lignes +0x2000 ou -0x2000 ---
mov ax, 0x2000 ; Banque +1 mov ax, 0x2000 ; Banque +1
mov cx, [BDA_MOUSE + mouse.y] mov cx, [PTR_MOUSE + mouse.y]
test cx, 1 test cx, 1
jz .setup_done jz .setup_done
neg ax ; banque -1 neg ax ; banque -1
@ -1529,28 +1531,20 @@ cga_cursor_draw:
.row_loop: .row_loop:
; --- CONSTRUCTION DES MASQUES (EAX/EBX) --- ; --- CONSTRUCTION DES MASQUES (EAX/EBX) ---
push cx ; préserver la banque "suivante" push cx ; préserver la banque "suivante"
mov cl, [BDA_MOUSE + mouse.x] mov cl, [PTR_MOUSE + mouse.x]
and cl, 0x07 and cl, 0x07
; --- MASQUE AND (EAX) --- ; --- MASQUE AND (EAX) ---
mov eax, 0xFFFFFFFF
mov ax, [gs:si] ; masque AND mov ax, [gs:si] ; masque AND
xchg al, ah ; Redresser pour l'ordre des pixels CGA
;bswap eax ; equivalence i386+
xchg ah, al ; Échange les octets de poids faible (AL <-> AH)
rol eax, 16 ; Bascule les 16 bits de poids fort vers le bas rol eax, 16 ; Bascule les 16 bits de poids fort vers le bas
mov ax, 0xFFFF
xchg ah, al ; Échange les nouveaux octets de poids faible xchg ah, al ; Échange les nouveaux octets de poids faible
; fin bswap eax equivalence i386+
ror eax, cl ror eax, cl
or eax, .mask ; Force les bits clippés à 1 (garde le fond) or eax, .mask ; Force les bits clippés à 1 (garde le fond)
; --- MASQUE XOR (EBX) --- ; --- MASQUE XOR (EBX) ---
xor ebx, ebx xor ebx, ebx
mov bx, [gs:si+32] ; masque XOR mov bx, [gs:si+32] ; masque XOR
;xchg bl, bh
;bswap ebx
rol ebx, 16 rol ebx, 16
xchg bh, bl xchg bh, bl
ror ebx, cl ror ebx, cl

View file

@ -28,6 +28,7 @@
%define GFX_MODE 0x12 ; VGA HiRes (640x480x16) %define GFX_MODE 0x12 ; VGA HiRes (640x480x16)
%define GFX_WIDTH 640 %define GFX_WIDTH 640
%define GFX_HEIGHT 480 %define GFX_HEIGHT 480
%define GFX_OFFSET 80
; ;
; bit : descr ; bit : descr
; 0 : text color : 0=black, 1=white ; 0 : text color : 0=black, 1=white
@ -74,7 +75,6 @@
%define MOUSE_HIDE 11 %define MOUSE_HIDE 11
%define MOUSE_SHOW 12 %define MOUSE_SHOW 12
%define MOUSE_MOVE 13 %define MOUSE_MOVE 13
%define MOUSE_DRAW 14
; ------------------------------------------------------------ ; ------------------------------------------------------------
; COMMENTAIRE SUR LA MÉTHODE D'APPEL ; COMMENTAIRE SUR LA MÉTHODE D'APPEL
@ -91,10 +91,10 @@ graph_driver:
dw vga_init ; init de la carte graphique dw vga_init ; init de la carte graphique
dw vga_putpixel ; dessin d'un pixel dw vga_putpixel ; dessin d'un pixel
dw vga_none ; lecture d'un pixel dw vga_none ; lecture d'un pixel
dw vga_none ; gotoxy dw vga_set_charpos ; gotoxy
dw vga_none ; mode texte dw vga_set_writemode ; mode texte
dw vga_none ; dessin d'un caractère dw vga_putc ; dessin d'un caractère
dw vga_none ; dessin d'une chaine de caractère dw vga_write ; dessin d'une chaine de caractère
dw vga_none ; dessin d'une ligne (Bresenham) avec décision horizontale/verticale dw vga_none ; dessin d'une ligne (Bresenham) avec décision horizontale/verticale
dw vga_none ; dessin d'un rectangle dw vga_none ; dessin d'un rectangle
dw vga_none ; dessin d'un rectangle plein dw vga_none ; dessin d'un rectangle plein
@ -102,7 +102,6 @@ graph_driver:
dw vga_mouse_hide ; cache la souris dw vga_mouse_hide ; cache la souris
dw vga_mouse_show ; montre la souris dw vga_mouse_show ; montre la souris
dw vga_mouse_cursor_move ; déplacement du curseur dw vga_mouse_cursor_move ; déplacement du curseur
dw vga_cursor_draw
; ------------------------------------------------------------ ; ------------------------------------------------------------
; dummy function ; dummy function
@ -116,7 +115,7 @@ vga_none:
; ------------------------------------------------------------ ; ------------------------------------------------------------
; initialise le mode graphique (via l'int 10h) ; initialise le mode graphique (via l'int 10h)
; ;
; ce mode est entrelacé, un bit/pixel, 8 pixels par octet ; ce mode est divisé en bitplane; 4 bits/pixel, 8 pixels par octet
; ------------------------------------------------------------ ; ------------------------------------------------------------
vga_init: vga_init:
; init graphics mode ; init graphics mode
@ -132,7 +131,6 @@ vga_init:
PATTERN_PTR PATTERN_GRAY_LIGHT PATTERN_PTR PATTERN_GRAY_LIGHT
mov bl, 15 mov bl, 15
call vga_background call vga_background
ISADBG ISA_GREEN, 0x88
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -190,7 +188,7 @@ vga_background:
; Boucle principale (480 lignes) ; Boucle principale (480 lignes)
xor edx, edx ; EDX servira d'index pour le pattern (0-7) xor edx, edx ; EDX servira d'index pour le pattern (0-7)
mov ecx, 480 mov ecx, GFX_HEIGHT
.line_loop: .line_loop:
mov al, [esi + edx] ; Charger l'octet du pattern pour la ligne actuelle mov al, [esi + edx] ; Charger l'octet du pattern pour la ligne actuelle
@ -221,6 +219,259 @@ vga_background:
; popad ; popad
ret ret
; ---------------------------------------------------------------------------
; gfx_set_writemode (mode)
; Défini le mode d'écriture :
;
; bit : descr
; 0 : text color : 0=black, 1=white
; 1 : transparent : 1=apply background attribut
;
; si le mode n'est pas transparent, la couleur de fond
; est l'inverse de la couleur du texte
; ---------------------------------------------------------------------------
; --- Définition des arguments ---
%define .mode word [bp+4]
vga_set_writemode:
push bp
mov bp, sp
push fs
push ax
mov ax, BDA_CUSTOM_SEG
mov fs,ax
mov ax, .mode
mov byte [fs:PTR_GFX + gfx.cur_mode], al
pop ax
pop fs
leave
ret
%undef .mode
; ---------------------------------------------------------------------------
; gfx_set_charpos (x,y)
; In : CX = x (pixels), DX = y (pixels)
; Out: variables DS:GFX_CUR_*
; Notes:
; - calcule l'offset VRAM de la scanline y: base = (y&1?2000:0) + (y>>1)*80 + (x>>3)
; - stocke aussi shift = x&7
; ---------------------------------------------------------------------------
; --- Définition des arguments ---
%define .x word [bp+4]
%define .y word [bp+6]
vga_set_charpos:
push bp
mov bp, sp
pusha
push fs
mov ax,BDA_CUSTOM_SEG
mov fs,ax
; store x,y en pixel
mov cx, .x
mov dx, .y
mov [fs:PTR_GFX + gfx.cur_x], cx
mov [fs:PTR_GFX + gfx.cur_y], dx
mov ax, cx
and ax, 0x07
mov [fs:PTR_GFX + gfx.cur_shift], al
call vga_calc_addr
mov [fs:PTR_GFX + gfx.cur_offset], bx
pop fs
popa
leave
ret
; clean defs
%undef .x
%undef .y
; ---------------------------------------------------------------------------
; get_glyph_offset
; In : AL = char (ASCII)
; Out: CS:SI -> 8 bytes
; ---------------------------------------------------------------------------
get_glyph_offset:
cmp al, 0x20
jb .qmark ; al < 20h (' '
cmp al, 0x7E
ja .qmark ; al > 7Eh ('~')
sub al, 0x20
jmp .ok
.qmark:
mov al, '?'
sub al, 0x20
.ok:
xor ah, ah
mov si, ax
shl si, 3
add si, font8x8
ret
; ---------------------------------------------------------------------------
; cga_putc_unalign (car)
; - x non aligné (x&7 != 0)
; - écrit sur 2 bytes (di et di+1) dans chaque banque
; ---------------------------------------------------------------------------
; convert al -> AX aligned with "cl"
%macro ALIGN_BYTE 0
mov ah,al
xor al,al
shr ax,cl
xchg ah,al
%endmacro
; --- Définition des arguments ---
%define .car word [bp+4]
vga_putc:
push bp
mov bp, sp
; --- Définition des variables locales ---
%define .cpt word [bp-2]
sub sp, 2 ; 1 word variable locale
pusha
push fs
push es
call vga_mouse_hide ; Protection souris
mov bx, VIDEO_SEG
mov es, bx
mov bx, BDA_CUSTOM_SEG
mov fs, bx
mov ax, .car
call get_glyph_offset
; Base offset VRAM pour la scanline Y
mov di, [fs:PTR_GFX + gfx.cur_offset]
mov ch, [fs:PTR_GFX + gfx.cur_mode]
mov cl, [fs:PTR_GFX + gfx.cur_shift]
mov bx, GFX_OFFSET
mov .cpt, 4
.row_loop:
; gestion du fond de texte
test ch, 00000010b ; transparent background ?
jz .skip_attribut ; oui
test ch, 00000001b ; background blanc ?
je .bkg_black
; background = white
mov ax, 0xFF00
shr ax, cl
xchg al, ah
or [es:di], ax
or [es:di+bx], ax
jmp .skip_attribut
.bkg_black: ; OK
; background = black
mov ax, 0xFF00
shr ax, cl
xchg al, ah
not ax
and [es:di], ax
and [es:di+bx], ax
.skip_attribut:
; ligne "paire" du gylphe
xor ax, ax
mov al, [cs:si]
inc si
ALIGN_BYTE
mov dx, ax
; ligne "impaire" du gylphe
mov al, [cs:si]
inc si
ALIGN_BYTE
xchg ax, dx
test ch,00000001b
jz .black_text
; white text
not ax
not dx
and [es:di], ax
and [es:di+bx], dx
jmp .next
.black_text:
or [es:di], ax
or [es:di+bx], dx
.next:
; add di,CGA_STRIDE
dec .cpt
jnz .row_loop
; Avancer curseur d'un caractère (8 pixels)
inc word [fs:PTR_GFX + gfx.cur_offset]
add word [fs:PTR_GFX + gfx.cur_x], 8
call vga_mouse_show ; Restauration souris
pop es
pop fs
popa
leave
ret
%undef .car
%undef .cpt
;
; write string from [DS:SI] to screen
;
; --- Définition des arguments ---
%define .txt_seg word [bp+4]
%define .txt_ofs word [bp+6]
vga_write:
push bp
mov bp, sp
push ax
push ds
mov ax, .txt_seg
mov ds, ax
mov si, .txt_ofs
cld
.loops:
lodsb
cmp al,0
je .done
push ax
call vga_putc
jmp .loops
.done:
pop ds
pop ax
leave
ret
%undef .txt_seg
%undef .txt_ofs
; Entrée: AX = X (0-639), BX = Y (0-479), CL = Couleur (0-15) ; Entrée: AX = X (0-639), BX = Y (0-479), CL = Couleur (0-15)
%define .x word [bp+4] %define .x word [bp+4]
%define .y word [bp+6] %define .y word [bp+6]
@ -302,10 +553,10 @@ vga_mouse_hide:
mov ds, ax mov ds, ax
; Décrémenter le compteur ; Décrémenter le compteur
dec byte [BDA_MOUSE + mouse.cur_counter] dec byte [PTR_MOUSE + mouse.cur_counter]
; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1) ; Vérifier si on vient juste de passer en mode caché (c-à-d on est à -1)
cmp byte [BDA_MOUSE + mouse.cur_counter], -1 cmp byte [PTR_MOUSE + mouse.cur_counter], -1
jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée jne .skip_restore ; Si on est à -2, -3... elle est déjà cachée
call vga_cursor_restorebg call vga_cursor_restorebg
@ -330,10 +581,10 @@ vga_mouse_show:
mov ds, ax mov ds, ax
; Incrémenter le compteur ; Incrémenter le compteur
inc byte [BDA_MOUSE + mouse.cur_counter] inc byte [PTR_MOUSE + mouse.cur_counter]
; Vérifier si on est revenu à 0 (Visible) ; Vérifier si on est revenu à 0 (Visible)
cmp byte [BDA_MOUSE + mouse.cur_counter], 0 cmp byte [PTR_MOUSE + mouse.cur_counter], 0
jne .skip_draw ; Si on est encore à -1, -2... on reste caché jne .skip_draw ; Si on est encore à -1, -2... on reste caché
; C'est la transition Caché -> Visible : On affiche le curseur ; C'est la transition Caché -> Visible : On affiche le curseur
@ -361,18 +612,18 @@ vga_mouse_cursor_move:
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov ds, ax mov ds, ax
cmp byte [BDA_MOUSE + mouse.cur_counter], 0 cmp byte [PTR_MOUSE + mouse.cur_counter], 0
jl .done ; Si < 0, on ne dessine rien ! jl .done ; Si < 0, on ne dessine rien !
cmp byte [BDA_MOUSE + mouse.cur_drawing],0 cmp byte [PTR_MOUSE + mouse.cur_drawing],0
jne .done jne .done
mov byte [BDA_MOUSE + mouse.cur_drawing],1 mov byte [PTR_MOUSE + mouse.cur_drawing],1
call vga_cursor_restorebg call vga_cursor_restorebg
call vga_cursor_savebg call vga_cursor_savebg
call vga_cursor_draw call vga_cursor_draw
mov byte [BDA_MOUSE + mouse.cur_drawing],0 mov byte [PTR_MOUSE + mouse.cur_drawing],0
.done: .done:
pop es pop es
pop ds pop ds
@ -382,7 +633,7 @@ vga_mouse_cursor_move:
; Buffer requis : 192 octets (16 lignes * 3 octets * 4 plans) ; Buffer requis : 192 octets (16 lignes * 3 octets * 4 plans)
; ATTENTION : Vérifiez que mouse.bkg_buffer dans bda.asm est assez grand ! ; ATTENTION : Vérifiez que mouse.bkg_buffer dans bda.asm est assez grand !
vga_cursor_savebg: vga_cursor_savebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
jne .done jne .done
push es push es
@ -390,12 +641,12 @@ vga_cursor_savebg:
mov es, ax mov es, ax
; Calculer l'adresse de départ (y * 80 + x / 8) ; Calculer l'adresse de départ (y * 80 + x / 8)
mov cx, [BDA_MOUSE + mouse.x] mov cx, [PTR_MOUSE + mouse.x]
mov dx, [BDA_MOUSE + mouse.y] mov dx, [PTR_MOUSE + mouse.y]
call vga_calc_addr ; Doit retourner DI = offset VRAM call vga_calc_addr ; Doit retourner DI = offset VRAM
mov [BDA_MOUSE + mouse.cur_addr_start], di mov [PTR_MOUSE + mouse.cur_addr_start], di
lea si, [BDA_MOUSE + mouse.bkg_buffer] lea si, [PTR_MOUSE + mouse.bkg_buffer]
mov dx, EGAVGA_CONTROLLER ; Graphics Controller Port mov dx, EGAVGA_CONTROLLER ; Graphics Controller Port
mov al, 0x04 ; Read Plane Select Register mov al, 0x04 ; Read Plane Select Register
@ -429,20 +680,20 @@ vga_cursor_savebg:
out dx, ax out dx, ax
pop es pop es
mov byte [BDA_MOUSE + mouse.bkg_saved], 1 mov byte [PTR_MOUSE + mouse.bkg_saved], 1
.done: .done:
ret ret
vga_cursor_restorebg: vga_cursor_restorebg:
cmp byte [BDA_MOUSE + mouse.bkg_saved], 0 cmp byte [PTR_MOUSE + mouse.bkg_saved], 0
je .done je .done
push es push es
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
mov es, ax mov es, ax
mov di, [BDA_MOUSE + mouse.cur_addr_start] mov di, [PTR_MOUSE + mouse.cur_addr_start]
lea si, [BDA_MOUSE + mouse.bkg_buffer] lea si, [PTR_MOUSE + mouse.bkg_buffer]
; Sécurité : S'assurer que ES pointe bien vers la vidéo pour le restore ; Sécurité : S'assurer que ES pointe bien vers la vidéo pour le restore
mov ax, VIDEO_SEG mov ax, VIDEO_SEG
@ -490,7 +741,7 @@ vga_cursor_restorebg:
out dx, ax out dx, ax
pop es pop es
mov byte [BDA_MOUSE + mouse.bkg_saved], 0 mov byte [PTR_MOUSE + mouse.bkg_saved], 0
.done: .done:
ret ret
@ -498,13 +749,16 @@ vga_cursor_restorebg:
; vga_cursor_draw ; vga_cursor_draw
; Détruit: registres sauvegardés/restaurés (PUSHA/POPA) ; Détruit: registres sauvegardés/restaurés (PUSHA/POPA)
; ============================================================ ; ============================================================
%define BYTES_SHIFT 3
vga_cursor_draw: vga_cursor_draw:
push bp push bp
mov bp, sp mov bp, sp
sub sp, 4 ; [bp-2]: height, [bp-4]: x_bit_offset ; local variables
; local variables %define .height word [bp-2]
%define .height word [bp-2] %define .bit_ofs word [bp-4]
%define .bit_ofs word [bp-4] %define .mask dword [bp-6]
sub sp, 8 ; [bp-2]: height, [bp-4]: x_bit_offset
pushad pushad
push ds push ds
@ -519,7 +773,7 @@ vga_cursor_draw:
mov es, ax mov es, ax
; --- CLIPPING VERTICAL --- ; --- CLIPPING VERTICAL ---
mov dx, [BDA_MOUSE + mouse.y] mov dx, [PTR_MOUSE + mouse.y]
mov bx, GFX_HEIGHT mov bx, GFX_HEIGHT
cmp dx, bx cmp dx, bx
jae .exit_total jae .exit_total
@ -533,8 +787,41 @@ vga_cursor_draw:
.y_ok: .y_ok:
mov .height, ax mov .height, ax
; --- CLIPPING HORIZONTAL ---
; On calcule si les 4 octets vont dépasser la ligne (80 octets)
; X est en bits (0-639). X >> 3 donne l'octet de départ (0-79).
; Si StartByte >= 77, on déborde.
mov cx, [PTR_MOUSE + mouse.x]
shr cx, 3 ; CX = Byte Offset (0-79)
xor eax, eax ; ESI = Masque de protection (0 = tout dessiner)
cmp cx, 76 ; 76 est le dernier offset sûr (76,77,78,79)
jbe .mask_ready ; Si <= 76, pas de débordement
; Calcul du débordement
; Si CX=77 (Déborde 1 byte) -> Masque 0x000000FF (LSB car bswap)
; Si CX=78 (Déborde 2 bytes)-> Masque 0x0000FFFF
; Si CX=79 (Déborde 3 bytes)-> Masque 0x00FFFFFF
cmp cx, 77
jne .check_78
mov eax, 0x000000FF
jmp .mask_ready
.check_78:
cmp cx, 78
jne .check_79
mov eax, 0x0000FFFF
jmp .mask_ready
.check_79:
mov eax, 0x00FFFFFF ; Cas extrême (bord droit)
.mask_ready:
mov .mask, eax
; --- Calcul Adresse et Shift --- ; --- Calcul Adresse et Shift ---
mov ax, [BDA_MOUSE + mouse.x] mov ax, [PTR_MOUSE + mouse.x]
mov cx, ax mov cx, ax
and ax, 7 ; Reste (0-7) = décalage de bit and ax, 7 ; Reste (0-7) = décalage de bit
mov .bit_ofs, ax mov .bit_ofs, ax
@ -545,7 +832,7 @@ vga_cursor_draw:
mov ax, 0x0F02 ; Map Mask = All planes mov ax, 0x0F02 ; Map Mask = All planes
out dx, ax out dx, ax
mov dx, 0x3CE ; Graphics Controller mov dx, EGAVGA_CONTROLLER
mov ax, 0x0005 ; Mode 0 mov ax, 0x0005 ; Mode 0
out dx, ax out dx, ax
mov ax, 0x0001 ; Enable Set/Reset = 0 (CPU Data) mov ax, 0x0001 ; Enable Set/Reset = 0 (CPU Data)
@ -554,53 +841,65 @@ vga_cursor_draw:
out dx, ax out dx, ax
; Source du Sprite -> (GS:SI) ; Source du Sprite -> (GS:SI)
mov ax, [BDA_MOUSE + mouse.cur_seg] mov ax, [PTR_MOUSE + mouse.cur_seg]
mov gs, ax mov gs, ax
mov si, [BDA_MOUSE + mouse.cur_ofs] mov si, [PTR_MOUSE + mouse.cur_ofs]
.row_loop: .row_loop:
; --- PREPARE MASKS --- mov dx, EGAVGA_CONTROLLER
; On récupère le masque de l'image (AND) et du curseur (XOR)
mov ax, [gs:si] ; AX = AND Mask (16 bits)
xchg al, ah ; Souvent nécessaire selon l'endianness du sprite
xor ebx, ebx
mov bx, ax
not ebx ; On veut des 1 partout sauf là où le curseur est présent
; Décalage pour l'alignement au pixel près
mov cx, .bit_ofs
ror ebx, cl ; Rotation pour ne pas perdre de bits
; --- CONFIG VGA POUR AND ---
mov dx, 0x3CE
mov ax, 0x0803 ; Data Rotate/Function Select: AND (bits 3-4 = 01b) mov ax, 0x0803 ; Data Rotate/Function Select: AND (bits 3-4 = 01b)
out dx, ax out dx, ax
; Application sur 3 octets (pour couvrir les 16 pixels + le shift) ; --- PASSE 1 : MASQUE AND (Effacement du fond) ---
%rep 3 mov ax, [gs:si] ; Charger 16 pixels (0=curseur, 1=fond)
mov al, [es:di] ; CHARGE LES LATCHES (Indispensable) shl eax, 16 ; décalage de AX vers le poid for: XXXX0000
mov eax, ebx mov ax, 0xFFFF
shr eax, 16 ; Récupère la partie haute (si 32-bit shift utilisé) mov cx, .bit_ofs
stosb ; Écrit AL et DI++ (Applique le AND sur les 4 plans) ror eax, cl ; Décaler : 1 là où on veut effacer (0 ailleurs)
%endrep or eax, .mask ; Appliquer le masque de clipping à droite
sub di, 3 ; Revient au début de la ligne pour le XOR
mov ebx, eax ; EBX contient le masque AND sur 3 octets
mov cx, BYTES_SHIFT ; Appliquer sur 3 octets (24 pixels potentiels)
.block_AND:
mov al, [es:di] ; Charger les latches VGA
rol ebx, 8 ; Extraire l'octet suivant (poids fort d'abord)
mov al, bl
stosb ; Écrire et DI++
loop .block_AND
sub di, BYTES_SHIFT ; Revenir au début de la ligne pour le XOR
; --- CONFIG VGA POUR XOR ---
mov ax, 0x1803 ; Data Rotate/Function Select: XOR (bits 3-4 = 11b) mov ax, 0x1803 ; Data Rotate/Function Select: XOR (bits 3-4 = 11b)
out dx, ax out dx, ax
; Récupération du masque XOR (la forme blanche/noire du curseur) ; --- PASSE 2 : MASQUE XOR (Dessin du curseur) ---
mov ax, [gs:si+32] xor eax, eax
; ... (Appliquer le même décalage et stosb que pour le AND) ... mov ax, [gs:si+32] ; Charger 16 pixels (1=blanc, 0=transparent)
movzx eax, ax ; S'assurer que le reste est à 0
shl eax, 16 ; Aligner
mov cx, .bit_ofs
shr eax, cl ; Décaler (les bits de padding restent à 0)
mov ebx, .mask ; Appliquer le masque de clipping à droite
not ebx
and eax, ebx ; Appliquer le masque de clipping à droite
mov ebx, eax ; EBX contient le masque XOR sur 3 octets
mov cx, BYTES_SHIFT
.block_XOR:
mov al, [es:di] ; Charger les latches
rol ebx, 8
mov al, bl
stosb
loop .block_XOR
; --- NEXT ROW --- ; --- NEXT ROW ---
add di, 80 - 3 ; Ligne suivante (80 octets par ligne) add di, 80 - BYTES_SHIFT ; Ligne suivante en VRAM (80 octets/ligne)
add si, 2 add si, 2
dec word .height dec word .height
jnz .row_loop jnz .row_loop
; --- RESTORE VGA --- ; --- RESTORE VGA ---
mov dx, 0x3CE mov dx, EGAVGA_CONTROLLER
mov ax, 0x0003 ; Function = Replace mov ax, 0x0003 ; Function = Replace
out dx, ax out dx, ax
mov ax, 0xFF08 ; Bit Mask = 0xFF mov ax, 0xFF08 ; Bit Mask = 0xFF
@ -614,6 +913,8 @@ vga_cursor_draw:
pop ds pop ds
popad popad
leave leave
%undef .height
%undef .bit_ofs
%undef .mask
ret ret
%undef .height
%undef .mask

View file

@ -47,28 +47,28 @@ mouse_reset:
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:PTR_MOUSE + mouse.idx],0
mov dword [fs:BDA_MOUSE + mouse.buffer],0 mov dword [fs:PTR_MOUSE + mouse.buffer],0
mov byte [fs:BDA_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut mov byte [fs:PTR_MOUSE + mouse.packetlen],3 ; 3 bytes par défaut
mov byte [fs:BDA_MOUSE + mouse.status],0 mov byte [fs:PTR_MOUSE + mouse.status],0
mov word [fs:BDA_MOUSE + mouse.x],GFX_WIDTH / 2 mov word [fs:PTR_MOUSE + mouse.x],GFX_WIDTH / 2
mov word [fs:BDA_MOUSE + mouse.y],GFX_HEIGHT / 2 mov word [fs:PTR_MOUSE + mouse.y],GFX_HEIGHT / 2
mov word [fs:BDA_MOUSE + mouse.cur_x], 0 mov word [fs:PTR_MOUSE + mouse.cur_x], 0
mov word [fs:BDA_MOUSE + mouse.cur_y], 0 mov word [fs:PTR_MOUSE + mouse.cur_y], 0
mov byte [BDA_MOUSE + mouse.cur_counter], -1 ; Force l'état caché au départ mov byte [fs:PTR_MOUSE + mouse.cur_counter], -1 ; Force l'état caché au départ
mov byte [BDA_MOUSE + mouse.cur_drawing], 0 ; Reset du verrou de dessin mov byte [fs:PTR_MOUSE + mouse.cur_drawing], 0 ; Reset du verrou de dessin
mov byte [BDA_MOUSE + mouse.bkg_saved],0 ; flag image saved mov byte [fs:PTR_MOUSE + mouse.bkg_saved],0 ; flag image saved
mov ax, cs mov ax, cs
mov word [fs:BDA_MOUSE + mouse.cur_seg], ax mov word [fs:PTR_MOUSE + mouse.cur_seg], ax
mov word [fs:BDA_MOUSE + mouse.cur_ofs], mouse_arrow mov word [fs:PTR_MOUSE + mouse.cur_ofs], mouse_arrow
; experiemntal ; experiemntal
mov byte [fs:BDA_MOUSE + mouse.wheel],0 mov byte [fs:PTR_MOUSE + mouse.wheel],0
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -157,7 +157,7 @@ mouse_detect_packet_len:
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov fs,ax mov fs,ax
mov byte [fs:BDA_MOUSE + mouse.packetlen], 3 mov byte [fs:PTR_MOUSE + mouse.packetlen], 3
; SET_RATE + 200 ; SET_RATE + 200
mov bl, MOUSE_SET_RATE mov bl, MOUSE_SET_RATE
@ -188,7 +188,7 @@ mouse_detect_packet_len:
je .is4 je .is4
ret ret
.is4: .is4:
mov byte [fs:BDA_MOUSE + mouse.packetlen], 4 mov byte [fs:PTR_MOUSE + mouse.packetlen], 4
ret ret
; ------------------------------------------------------------ ; ------------------------------------------------------------
@ -280,7 +280,7 @@ mouse_sendcmd:
; ------------------------------------------------------------ ; ------------------------------------------------------------
isr_mouse_handler: isr_mouse_handler:
; sauvegarder tout les registres ; sauvegarder tout les registres
pusha pushad
push ds push ds
; use BDA segment ; use BDA segment
@ -290,7 +290,7 @@ isr_mouse_handler:
; 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 [PTR_MOUSE + mouse.idx]
cmp bl,0 cmp bl,0
jne .read_packet jne .read_packet
@ -298,88 +298,88 @@ isr_mouse_handler:
test al, 00001000b ; bit 3 = 1 test al, 00001000b ; bit 3 = 1
jz .done_eoi ; allignement erroné jz .done_eoi ; allignement erroné
.read_packet: .read_packet:
mov byte [BDA_MOUSE + mouse.buffer + bx], al mov byte [PTR_MOUSE + mouse.buffer + bx], al
inc byte [BDA_MOUSE + mouse.idx] inc byte [PTR_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, byte [PTR_MOUSE + mouse.packetlen]
cmp byte [BDA_MOUSE + mouse.idx], al cmp byte [PTR_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 [PTR_MOUSE + mouse.idx], 0 ; reset de l'index de lecture
; debut du décodage des données ; debut du décodage des données
mov bl, [BDA_MOUSE + mouse.buffer] ; status mov bl, byte [PTR_MOUSE + mouse.buffer] ; status
; --- BOUTONS --- ; --- BOUTONS ---
mov al,bl ; extraction des boutons mov al, bl ; extraction des boutons
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 [PTR_MOUSE + mouse.status], al
xor ax,ax xor ax,ax
mov al, byte [BDA_MOUSE + mouse.buffer+1] ; delta X mov al, byte [PTR_MOUSE + mouse.buffer+1] ; delta X
test bl,00010000b ; signe X (4eme bit) test bl, 00010000b ; signe X (4eme bit)
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 [PTR_MOUSE + mouse.x], ax
xor ax,ax xor ax,ax
mov al, byte [BDA_MOUSE + mouse.buffer+2] ; delta Y mov al, byte [PTR_MOUSE + mouse.buffer+2] ; delta Y
test bl,00100000b ; signe Y (5eme bit) test bl, 00100000b ; signe Y (5eme bit)
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 [PTR_MOUSE + mouse.y], ax
; --- CLAMPING X --- ; --- CLAMPING X ---
; Check minimum (0) ; Check minimum (0)
cmp word [BDA_MOUSE + mouse.x], 0 cmp word [PTR_MOUSE + mouse.x], 0
jge .check_x_max jge .check_x_max
mov word [BDA_MOUSE + mouse.x], 0 mov word [PTR_MOUSE + mouse.x], 0
jmp .done_x jmp .done_x
.check_x_max: .check_x_max:
; Check maximum (e.g., 639 for graphics, or pixel width) ; Check maximum (e.g., 639 for graphics, or pixel width)
cmp word [BDA_MOUSE + mouse.x], GFX_WIDTH-1 ; Replace with variable or define cmp word [PTR_MOUSE + mouse.x], GFX_WIDTH-1 ; Replace with variable or define
jle .done_x jle .done_x
mov word [BDA_MOUSE + mouse.x], GFX_WIDTH-1 mov word [PTR_MOUSE + mouse.x], GFX_WIDTH-1
.done_x: .done_x:
; --- CLAMPING Y --- ; --- CLAMPING Y ---
; Check minimum (0) ; Check minimum (0)
cmp word [BDA_MOUSE + mouse.y], 0 cmp word [PTR_MOUSE + mouse.y], 0
jge .check_y_max jge .check_y_max
mov word [BDA_MOUSE + mouse.y], 0 mov word [PTR_MOUSE + mouse.y], 0
jmp .done_y jmp .done_y
.check_y_max: .check_y_max:
; Check maximum ; Check maximum
cmp word [BDA_MOUSE + mouse.y], GFX_HEIGHT-1 ; Replace with variable or define cmp word [PTR_MOUSE + mouse.y], GFX_HEIGHT-1 ; Replace with variable or define
jle .done_y jle .done_y
mov word [BDA_MOUSE + mouse.y], GFX_HEIGHT-1 mov word [PTR_MOUSE + mouse.y], GFX_HEIGHT-1
.done_y: .done_y:
; 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, [PTR_MOUSE + mouse.packetlen]
cmp al,4 cmp al,4
jne .done jne .done
; 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 [PTR_MOUSE + mouse.buffer+3] ; delta Wheel
add word [BDA_MOUSE + mouse.wheel], ax add word [PTR_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 cga_mouse_cursor_move ; call cga_mouse_cursor_move
GFX MOUSE_MOVE GFX MOUSE_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 popad
iret iret

View file

@ -23,7 +23,7 @@ gui_process_all:
push ds push ds
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov ds, ax mov ds, ax
mov bl, [BDA_MOUSE + mouse.status] mov bl, [PTR_MOUSE + mouse.status]
pop ds pop ds
mov si, 0 ; Pointeur début tableau mov si, 0 ; Pointeur début tableau
@ -97,8 +97,8 @@ gui_update_logic:
xor ax, ax xor ax, ax
; les macros peuvent modifer les registres cx, dx & bx ; les macros peuvent modifer les registres cx, dx & bx
mov cx, [BDA_MOUSE + mouse.x] mov cx, [PTR_MOUSE + mouse.x]
mov dx, [BDA_MOUSE + mouse.y] mov dx, [PTR_MOUSE + mouse.y]
; --- Hit Test --- ; --- Hit Test ---
cmp cx, [gs:si + widget.x] cmp cx, [gs:si + widget.x]
@ -115,7 +115,7 @@ gui_update_logic:
cmp dx, bx cmp dx, bx
ja .miss ; mouse.y >= widget.y ? ja .miss ; mouse.y >= widget.y ?
mov bl, [BDA_MOUSE + mouse.status] mov bl, [PTR_MOUSE + mouse.status]
.case_0: .case_0:
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
@ -437,7 +437,7 @@ gui_logic_slider:
push ds push ds
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov ds, ax mov ds, ax
mov ax, [BDA_MOUSE + mouse.x] mov ax, [PTR_MOUSE + mouse.x]
pop ds pop ds
sub ax, [gs:si + widget.attr_anchor] sub ax, [gs:si + widget.attr_anchor]
@ -465,7 +465,7 @@ gui_logic_slider:
push ds push ds
mov ax, BDA_CUSTOM_SEG mov ax, BDA_CUSTOM_SEG
mov ds, ax mov ds, ax
mov ax, [BDA_MOUSE + mouse.y] mov ax, [PTR_MOUSE + mouse.y]
pop ds pop ds
sub ax, [gs:si + widget.attr_anchor] sub ax, [gs:si + widget.attr_anchor]