diff --git a/doc/MEMORY_MAP.md b/doc/MEMORY_MAP.md index 9e09988..53d4f4c 100644 --- a/doc/MEMORY_MAP.md +++ b/doc/MEMORY_MAP.md @@ -6,22 +6,21 @@ The processor starts in Real Mode, addressing 1 MB of memory. -| Physical Start | Physical End | Size | Description | Segment | Source File | +| Physical Start | Physical End | Size | Description | Segment | Source/Definied | | :--- | :--- | :--- | :--- | :--- | :--- | | **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` | | **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` | -| **`0x00500`** | **`0x005FF`** | ~256 B | **Custom BDA** (Driver Data) | `0x0050` | `memory.asm` | +| **`0x00500`** | **`0x005FF`** | 256 B | **Custom BDA** (Driver Data) | `0x0050` | `memory.asm` | | **`0x00600`** | **`0x00AFF`** | 1.25 KB | **GUI RAM** (Widget Allocation) | `0x0060` | `gui/lib.asm` | | **`0x00B00`** | **`0x07FFF`** | 29 KB | **Free** (Low Memory) | | | -| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `memory.asm` | -| **`0x18000`** | **`0x9FBFF`** | 543 KB | **Free** (Conventional RAM) | | | -| **`0x9FC00`** | **`0x9FFFF`** | 1 KB | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` | +| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` | +| **`0x18000`** | **`0x9FFFF`** | 544 KB | **Free** (Conventional RAM) | | | | **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` | | **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` | -| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `memory.asm` | -| **`0xC0000`** | **`0xDFFFF`** | 128 KB | **Option ROMs** (e.g., VGA BIOS) | `0xC000` | `memory.asm` | +| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` | +| **`0xC0000`** | **`0xDFFFF`** | 128 KB | **Option ROMs** (e.g., VGA BIOS) | `0xC000` | `generic.asm` | | **`0xE0000`** | **`0xEFFFF`** | 64 KB | **System Reserved** (BIOS Extension) | `0xE000` | `Hardware` | -| **`0xF0000`** | **`0xFFFFF`** | 64 KB | **System BIOS ROM** (Code) | `0xF000` | `memory.asm` | +| **`0xF0000`** | **`0xFFFFF`** | 64 KB | **System BIOS ROM** (Code) | `0xF000` | `Hardware` | ### Detailed Zones @@ -43,7 +42,7 @@ The project separates the standard IBM BDA from its own variables to avoid confl * **Layout**: Located in low memory (`0x0060`) to avoid any collision with the Stack (`0x0800`). #### Stack -* **Stack**: Segment `0x0800`, SP `0xFFFE`. Grows downwards from physical address `0x17FFE`. +* **Stack**: Grows downwards from physical address `0xFFFE` (16-bit aligned) of the "Stack Segment" defined by `STACK_SEG`. #### Video RAM (CGA High-Res) * **Segment**: `0xB800` @@ -68,22 +67,21 @@ The project separates the standard IBM BDA from its own variables to avoid confl Le processeur démarre en mode réel, adressant 1 Mo de mémoire. -| Adresse Physique (Début) | Adresse Physique (Fin) | Taille | Description | Segment | Fichier Source | +| Physical Start | Physical End | Size | Description | Segment | Source/Definied | | :--- | :--- | :--- | :--- | :--- | :--- | -| **`0x00000`** | **`0x003FF`** | 1 Ko | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` | -| **`0x00400`** | **`0x004FF`** | 256 o | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` | -| **`0x00500`** | **`0x005FF`** | ~256 o | **Custom BDA** (Données Drivers) | `0x0050` | `memory.asm` | -| **`0x00600`** | **`0x00AFF`** | 1.25 Ko | **GUI RAM** (Allocation Widgets) | `0x0060` | `gui/lib.asm` | -| **`0x00B00`** | **`0x07FFF`** | 29 Ko | **Libre** (Mémoire Basse) | | | -| **`0x08000`** | **`0x17FFF`** | 64 Ko | **Pile** (Stack) | `0x0800` | `memory.asm` | -| **`0x18000`** | **`0x9FBFF`** | 543 Ko | **Libre** (RAM Conventionnelle) | | | -| **`0x9FC00`** | **`0x9FFFF`** | 1 Ko | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` | -| **`0xA0000`** | **`0xAFFFF`** | 64 Ko | **VGA RAM** (Modes Graphiques) | `0xA000` | `Matériel` | -| **`0xB0000`** | **`0xB7FFF`** | 32 Ko | **MDA RAM** (Texte Monochrome) | `0xB000` | `Matériel` | -| **`0xB8000`** | **`0xBFFFF`** | 32 Ko | **VRAM** (CGA / MCGA) | `0xB800` | `memory.asm` | -| **`0xC0000`** | **`0xDFFFF`** | 128 Ko | **Option ROMs** (ex: VGA BIOS) | `0xC000` | `memory.asm` | -| **`0xE0000`** | **`0xEFFFF`** | 64 Ko | **Réservé Système** (Extension BIOS) | `0xE000` | `Matériel` | -| **`0xF0000`** | **`0xFFFFF`** | 64 Ko | **System BIOS ROM** (Code) | `0xF000` | `memory.asm` | +| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` | +| **`0x00400`** | **`0x004FF`** | 256 B | **BDA** (BIOS Data Area) Standard | `0x0040` | `memory.asm` | +| **`0x00500`** | **`0x005FF`** | 256 B | **Custom BDA** (Driver Data) | `0x0050` | `memory.asm` | +| **`0x00600`** | **`0x00AFF`** | 1.25 KB | **GUI RAM** (Widget Allocation) | `0x0060` | `gui/lib.asm` | +| **`0x00B00`** | **`0x07FFF`** | 29 KB | **Free** (Low Memory) | | | +| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `boot.asm` | +| **`0x18000`** | **`0x9FFFF`** | 544 KB | **Free** (Conventional RAM) | | | +| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` | +| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` | +| **`0xB8000`** | **`0xBFFFF`** | 32 KB | **VRAM** (CGA / MCGA) | `0xB800` | `generic.asm` | +| **`0xC0000`** | **`0xDFFFF`** | 128 KB | **Option ROMs** (e.g., VGA BIOS) | `0xC000` | `generic.asm` | +| **`0xE0000`** | **`0xEFFFF`** | 64 KB | **System Reserved** (BIOS Extension) | `0xE000` | `Hardware` | +| **`0xF0000`** | **`0xFFFFF`** | 64 KB | **System BIOS ROM** (Code) | `0xF000` | `Hardware` | ### Détails des Zones @@ -105,7 +103,7 @@ Le projet sépare la BDA standard IBM de ses propres variables pour éviter les * **Organisation** : Située en mémoire basse (`0x0060`) pour éviter toute collision avec la Pile (`0x0800`). #### Stack -* **Stack** : Segment `0x0800`, SP `0xFFFE`. Grandit vers le bas depuis l'adresse physique `0x17FFE`. +* **Stack** : Grandit vers le bas depuis l'adresse physique `0xFFFE` (Alignement sur 16 bits) du "stack Segment" défini par `STACK_SEG`. #### Video RAM (CGA High-Res) diff --git a/src/boot.asm b/src/boot.asm index 9f4a70d..84123e8 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -60,17 +60,24 @@ section .text %include "./gui/lib.asm" %include "./gui/draw.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 - ; il n'existe aucun 'stack' par défaut - mov ax, STACK_SEG + 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 - ; installé une table d'interruption "dummy" - call ivt_setup - call bda_setup + 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 @@ -80,15 +87,23 @@ entrycode: call ivt_setvector + ISADBG ISA_GREEN, 2 + ; initialisation des PIC 8259A call pic_init + ISADBG ISA_GREEN, 4 + ; load Roms call setup_load_rom + ISADBG ISA_GREEN, 8 + ; on vérifie que le BIOS VGA a installé une INT 10h call setup_check_vga + ISADBG ISA_GREEN, 16 + ; enable IRQ 0 mov ah,IRQ_ENABLED mov al,0 @@ -97,13 +112,24 @@ entrycode: call kbd_init sti + DEBUG 0xFADE + + ISADBG ISA_GREEN, 32 + ; on active le mode graphique GFX INIT call mouse_init - GFX MOUSE_MOVE - GFX MOUSE_SHOW + 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: @@ -111,26 +137,37 @@ on_click_quit: jmp on_click_quit ret -%define .oldval word [bp-2] -%define .slider word [bp-4] +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, 4 + sub sp, 6 push cs pop ds + DEBUG 1 + ISADBG ISA_RED, 1 + ; Init du système GUI call gui_init_system + + DEBUG 2 + ISADBG ISA_RED, 2 + ; --- CRÉATION DYNAMIQUE DES BOUTONS --- ; Créer Bouton 1 "QUITTER" GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 10, 10, 80, 16 GUI OBJ_SET_TEXT, ax, cs, str_quit ; Créer Bouton 2 "HELLO" - GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 100, 50, 80, 16, + GUI OBJ_CREATE, OBJ_TYPE_BUTTON_ROUNDED, 100, 50, 80, 16 GUI OBJ_SET_TEXT, ax, cs, str_hello ; Créer checkbox 3 "option 1" GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50, 100, 15 @@ -142,43 +179,52 @@ main_loop: GUI OBJ_CREATE, OBJ_TYPE_CHECKBOX, 200, 50+16*2, 100, 15 GUI OBJ_SET_TEXT, ax, cs, str_option3 + DEBUG 3 + ISADBG ISA_RED, 3 + ; Créer Slider (Drag) GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 10, 100, 150, 12 GUI OBJ_SET_MODE, ax, SLIDER_HORIZONTAL GUI OBJ_SLIDER_SET_ATTR, ax, 10, 140, 10, 15 GUI OBJ_CREATE, OBJ_TYPE_SLIDER, 400, 10, 16, 150 - mov .slider, ax - GUI OBJ_SET_MODE, .slider, SLIDER_VERTICAL - GUI OBJ_SLIDER_SET_ATTR, .slider, 0, 15, 15, 20 - mov .oldval, -1 + mov .my_slider, ax + + GUI OBJ_SET_MODE, .my_slider, SLIDER_VERTICAL + GUI OBJ_SLIDER_SET_ATTR, .my_slider, 0, 15, 15, 12 + + mov .oldval, 0x1256 + mov .value, 0xFADE + + DEBUG 4 + ISADBG ISA_RED, 4 .loop: - call gui_process_all - GUI OBJ_GET_VAL, .slider ; slider + call gui_process_all + GUI OBJ_GET_VAL, .my_slider + mov .value, ax - cmp ax,.oldval - je .loop + cmp ax,.oldval + je .loop - ; debug - mov .oldval, ax - GFX RECTANGLE_FILL,0,148,50,166, PATTERN_WHITE - GFX GOTOXY, 8, 150 + ; debug + mov .oldval, ax + GFX RECTANGLE_FILL,0,148,50,166, PATTERN_WHITE + GFX GOTOXY, 8, 150 - call print_word_hex - ; end debug + mov ax, .value + call print_word_hex + ; end debug + + mov dx, 0x3d9 + mov ax, .value + and ax, 0x000F + out dx, al jmp .loop leave ret -; --- Données ROM --- -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 - ; ----------------------------------------------------------- ; timer ISR (IRQ -> INT) ; ----------------------------------------------------------- diff --git a/src/common/bda.asm b/src/common/bda.asm index 2615e85..f4d18f2 100644 --- a/src/common/bda.asm +++ b/src/common/bda.asm @@ -78,16 +78,6 @@ endstruc %define BDA_MOUSE 0x0000 %define BDA_GFX (BDA_MOUSE + mouse_size) -; -; memory map -; -; 0x00000-0x003FF : IVT (1kB) -; 0x00400-0x007FF : BDA (1kB) pour les options 'ROMS' carte graphique, etc... -; 0x00800-0x009FF : Varibles custom. -; -; 0x03C00-0x08000 : stack segment -; 0x - ; ----------------------------------------------------------------------------------- ; bda_setup ; Initialise la BDA à zéro diff --git a/src/common/cursor.asm b/src/common/cursor.asm index 1ada67f..87aaef5 100644 --- a/src/common/cursor.asm +++ b/src/common/cursor.asm @@ -4,35 +4,35 @@ %define CURSOR_H 16 mouse_arrow: - dw 1001111111111111b ; 0x9FFF - dw 1000111111111111b ; 0x8FFF - dw 1000011111111111b ; 0x87FF - dw 1000001111111111b ; 0x83FF - dw 1000000111111111b ; 0x81FF - dw 1000000011111111b ; 0x80FF - dw 1000000001111111b ; 0x807F - dw 1000000000111111b ; 0x803F - dw 1000000000011111b ; 0x801F - dw 1000000000001111b ; 0x800F - dw 1000000011111111b ; 0x80FF - dw 1000100001111111b ; 0x887F - dw 1001100001111111b ; 0x987F - dw 1111110000111111b ; 0xFC3F - dw 1111110000111111b ; 0xFC3F - dw 1111111000111111b ; 0xFE3F - dw 0000000000000000b ; 0x0000 - dw 0010000000000000b ; 0x2000 - dw 0011000000000000b ; 0x3000 - dw 0011100000000000b ; 0x3800 - dw 0011110000000000b ; 0x3C00 - dw 0011111000000000b ; 0x3E00 - dw 0011111100000000b ; 0x3F00 - dw 0011111110000000b ; 0x3F80 - dw 0011111111000000b ; 0x3FC0 - dw 0011111000000000b ; 0x3E00 - dw 0011011000000000b ; 0x3600 - dw 0010001100000000b ; 0x2300 - dw 0000001100000000b ; 0x0300 - dw 0000000110000000b ; 0x0180 - dw 0000000110000000b ; 0x0180 - dw 0000000000000000b ; 0x0000 + dw 1001111111111111b ; 0x9FFF + dw 1000111111111111b ; 0x8FFF + dw 1000011111111111b ; 0x87FF + dw 1000001111111111b ; 0x83FF + dw 1000000111111111b ; 0x81FF + dw 1000000011111111b ; 0x80FF + dw 1000000001111111b ; 0x807F + dw 1000000000111111b ; 0x803F + dw 1000000000011111b ; 0x801F + dw 1000000000001111b ; 0x800F + dw 1000000011111111b ; 0x80FF + dw 1000100001111111b ; 0x887F + dw 1001100001111111b ; 0x987F + dw 1111110000111111b ; 0xFC3F + dw 1111110000111111b ; 0xFC3F + dw 1111111000111111b ; 0xFE3F + dw 0000000000000000b ; 0x0000 + dw 0010000000000000b ; 0x2000 + dw 0011000000000000b ; 0x3000 + dw 0011100000000000b ; 0x3800 + dw 0011110000000000b ; 0x3C00 + dw 0011111000000000b ; 0x3E00 + dw 0011111100000000b ; 0x3F00 + dw 0011111110000000b ; 0x3F80 + dw 0011111111000000b ; 0x3FC0 + dw 0011111000000000b ; 0x3E00 + dw 0011011000000000b ; 0x3600 + dw 0010001100000000b ; 0x2300 + dw 0000001100000000b ; 0x0300 + dw 0000000110000000b ; 0x0180 + dw 0000000110000000b ; 0x0180 + dw 0000000000000000b ; 0x0000 diff --git a/src/common/generic.asm b/src/common/generic.asm index 92a0d88..2f70cae 100644 --- a/src/common/generic.asm +++ b/src/common/generic.asm @@ -20,6 +20,45 @@ ; ; ============================================================================= +%macro DEBUG 1 + GFX GOTOXY, 0, 0 + mov ax, %1 + call print_word_hex +%endmacro + +; +; Debugger for 86Box +; +%define ISA_DBG_PORT 0x007a +; +%define ISA_RED 0 +%define ISA_GREEN 1 +%define ISA_RIGHT 2 +%define ISA_LEFT 3 +%define ISA_RESET 0xff + +%macro ISADBG 2 + push dx + push ax + mov dx, ISA_DBG_PORT + mov al, byte %1 + out dx, al + inc dx + mov al, byte %2 + out dx, al + pop ax + pop dx +%endmacro + +%macro ISADBG_RESET 0 + push dx + push ax + mov dx, ISA_DBG_PORT + mov al, ISA_RESET + out dx, al + pop ax + pop dx +%endmacro ; ----------------------------------------------------------------------------------- ; PC components I/O ports diff --git a/src/drivers/gfx_cgam.asm b/src/drivers/gfx_cgam.asm index b40ce60..99361ac 100644 --- a/src/drivers/gfx_cgam.asm +++ b/src/drivers/gfx_cgam.asm @@ -120,7 +120,6 @@ cga_init: mov al, GFX_MODE int 0x10 - ; mov byte [BDA_GFX + gfx.cur_mode], 1 ; dessine un background "check-board" call cga_background ret @@ -161,7 +160,6 @@ cga_calc_addr: shr ah, cl ret - ; --------------------------------------------------------------------------- ; gfx_set_writemode (mode) ; Défini le mode d'écriture : @@ -418,6 +416,7 @@ cga_write: mov ax, .txt_seg mov ds, ax mov si, .txt_ofs + cld .loops: lodsb @@ -529,6 +528,7 @@ cga_background: mov es,ax mov di,0x0000 mov eax,0xaaaaaaaa + cld mov cx,0x800 rep stosd mov di,0x2000 @@ -1019,7 +1019,7 @@ cga_fill_rect: call cga_mouse_hide - ; --- 1. Tri des coordonnées (X et Y) --- + ; --- Tri des coordonnées (X et Y) --- ; Tri X mov ax, .x1 mov bx, .x2 @@ -1045,14 +1045,14 @@ cga_fill_rect: and ax, 7 mov .pat_idx, ax - ; --- 2. Calcul de la hauteur --- + ; --- Calcul de la hauteur --- mov bx, .y2 sub bx, .y1 inc bx ; BX = Hauteur finale push bx ; SAUVEGARDER LA HAUTEUR SUR LA PILE [STACK A] ; (Car on va utiliser BX dans cga_calc_addr ou juste après) - ; --- 3. Calcul adresse de départ --- + ; --- Calcul adresse de départ --- mov cx, .x1 mov dx, .y1 @@ -1061,7 +1061,7 @@ cga_fill_rect: ; Si cga_calc_addr modifie BX, la sauvegarde [STACK A] est vitale. call cga_calc_addr ; DI = Offset début ligne - ; --- 4. Préparer les masques --- + ; --- Préparer les masques --- ; Masque Gauche (DH) mov cx, .x1 and cx, 7 @@ -1083,7 +1083,7 @@ cga_fill_rect: shr cx, 3 ; CX = Index end byte mov .x_end_idx, cx ; Sauvegarde de l'index de fin pour la boucle horizontale - ; --- 5. Récupérer la hauteur dans un registre sûr --- + ; --- Récupérer la hauteur dans un registre sûr --- pop bx ; RESTAURER HAUTEUR DANS BX [STACK A] ; BX est maintenant notre compteur de boucle. ; --- BOUCLE VERTICALE --- @@ -1313,7 +1313,7 @@ cga_mouse_show: .skip_draw: pop ds popad - popf + popf ; restore également le flag d'interruption ret diff --git a/src/gui/draw.asm b/src/gui/draw.asm index 281422c..3db5cd9 100644 --- a/src/gui/draw.asm +++ b/src/gui/draw.asm @@ -27,6 +27,7 @@ ; Dessine le widget pointé par SI gui_draw_single_widget: pusha + push es GFX MOUSE_HIDE ; On cache la souris AVANT de commencer le dessin du widget @@ -88,6 +89,7 @@ gui_draw_single_widget: .done: GFX MOUSE_SHOW ; On réaffiche la souris APRES, capturant le widget fini + pop es popa ret @@ -127,8 +129,8 @@ draw_slider: mov bx, 100 div bx ; AX = Thumb Width - ; Thumb X1 = attr_val - mov cx, [gs:si + widget.attr_val] + ; Thumb X1 = thumb_pos + mov cx, [gs:si + widget.thumb_pos] ; --- CLAMP X1 (Fix Overflow) --- ; Max X1 = TrackX2 - ThumbW @@ -166,8 +168,8 @@ draw_slider: mov bx, 100 div bx ; AX = Thumb Height - ; Thumb Y1 = attr_val - mov cx, [gs:si + widget.attr_val] + ; Thumb Y1 = thumb_pos + mov cx, [gs:si + widget.thumb_pos] ; --- CLAMP Y1 (Fix Overflow) --- ; Max Y1 = TrackY2 - ThumbH @@ -413,7 +415,7 @@ draw_checkbox: GFX RECTANGLE, ax, bx, cx, dx, 0 ; Check if checked - cmp word [gs:si + widget.attr_val], 0 + cmp word [gs:si + widget.thumb_pos], 0 je .draw_label ; Dessin du X (Diagonales) @@ -465,6 +467,7 @@ draw_label: ; affiche le texte au centre du widget gs:si ; draw_text: + push es ; --- Centrage Texte --- mov es, [gs:si + widget.text_seg] mov di, [gs:si + widget.text_ofs] @@ -499,4 +502,5 @@ draw_text: mov dx, [gs:si + widget.text_seg] mov ax, [gs:si + widget.text_ofs] GFX WRITE, dx, ax + pop es ret \ No newline at end of file diff --git a/src/gui/lib.asm b/src/gui/lib.asm index 3cd8990..1586a44 100644 --- a/src/gui/lib.asm +++ b/src/gui/lib.asm @@ -21,7 +21,7 @@ ; ============================================================================= ; --- Configuration --- -%define GUI_RAM_SEG 0x060 ; Segment de données UI (Safe: après Stack, avant Heap) +%define GUI_RAM_SEG 0x080 ; Segment de données UI (Safe: après Stack, avant Heap) %define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés ; Dimensions @@ -94,17 +94,18 @@ struc widget .h resw 1 ; Hauteur .text_ofs resw 1 ; Offset du texte .text_seg resw 1 ; Segment du texte - .event_click resw 1 ; adresse de la fonction "on click" - .event_drag resw 1 ; adresse de la fonction "on drag" + .event_click resw 1 ; adresse de la fonction "on click" + .event_drag resw 1 ; adresse de la fonction "on drag" - .attr_mode resb 1 ; 0=None, 1=Horiz, 2=Vert - .attr_min resw 1 ; Valeur/Position Min - .attr_max resw 1 ; Valeur/Position Max - .attr_val resw 1 ; Valeur/Position Actuelle + .attr_mode resb 1 ; 0=None, 1=Horiz, 2=Vert + .attr_min resw 1 ; Valeur/Position Min + .attr_max resw 1 ; Valeur/Position Max + .attr_val resw 1 ; Valeur/Position Actuelle - .thumb_pct resb 1 ; Taille du curseur en % (1-100) + .thumb_pos resw 1 ; Valeur/Position Actuelle en pixel pour le dessin. + .thumb_pct resb 1 ; Taille du curseur en % (1-100) - .attr_anchor resw 1 ; interne Offset pour le drag + .attr_anchor resw 1 ; interne Offset pour le drag alignb 2 ; Alignement mémoire pour performance endstruc ; actuellement 34 octets @@ -145,6 +146,8 @@ gui_api_slider_attr: mov ax, .pct mov byte [gs:si + widget.thumb_pct], al + call gui_slider_update_pixels + .err: pop ax leave @@ -317,10 +320,10 @@ gui_api_get_val: push bp mov bp, sp - mov ax, .id ; ID call gui_get_widget_ptr - jc .err + ;jc .err + call gui_slider_update_value mov ax, [gs:si + widget.attr_val] jmp .done @@ -347,7 +350,7 @@ gui_api_set_val: jc .err mov ax, .val - mov [gs:si + widget.attr_val], ax + mov [gs:si + widget.thumb_pos], ax .err: leave @@ -391,26 +394,32 @@ gui_api_destroy: gui_get_widget_ptr: push bp mov bp, sp + push ax + push cx mov ax, .id - stc - cmp ax, GUI_MAX_WIDGETS - je .done + jae .error - push dx mov cx, widget_size + xor dx, dx mul cx ; AX = Offset mov si, ax - pop dx mov ax, GUI_RAM_SEG mov gs, ax clc -.done: + jmp .done + .error: + stc + .done: + pop cx + pop ax leave ret +%undef .id + ; ============================================================================= ; SECTION : GESTION MÉMOIRE (ALLOCATION / LIBÉRATION) @@ -430,6 +439,7 @@ gui_init_system: mov ax, GUI_RAM_SEG mov es, ax + cld xor di, di mov cx, (widget_size * GUI_MAX_WIDGETS) / 2 xor ax, ax @@ -500,6 +510,7 @@ gui_free_widget: mov ax, GUI_RAM_SEG mov es, ax + cld mov di, si mov cx, (widget_size) shr cx, 2 ; cx / 4 @@ -704,6 +715,137 @@ gui_logic_button: xor ax, ax ret + +; ----------------------------------------------------------------------------- +; gui_slider_update_value +; In: GS:SI = widget +; Calcule .attr_val à partir de .thumb_pos (pixels) +; ----------------------------------------------------------------------------- +gui_slider_update_value: + push eax + push ebx + push ecx + push edx + + cmp byte [gs:si + widget.type], OBJ_TYPE_SLIDER + jne .done + + ; Calculer RangePix (Amplitude totale de mouvement en pixels) + movzx eax, word [gs:si + widget.w] ; Largeur par défaut + cmp byte [gs:si + widget.attr_mode], SLIDER_VERTICAL + jne .calc_thumb + movzx eax, word [gs:si + widget.h] ; Hauteur si vertical + + .calc_thumb: + push eax ; Sauvegarde la dimension totale + movzx ebx, byte [gs:si + widget.thumb_pct] + mul ebx ; EAX = Dim * pct + mov ebx, 100 + xor edx, edx + div ebx ; EAX = Taille physique du curseur + + pop ebx ; EBX = Dimension totale + sub ebx, eax ; EBX = RangePix (Place disponible) + jz .done ; Si 0, division impossible + + + ; Calculer DeltaPix (Distance parcourue par le curseur) + movzx eax, word [gs:si + widget.thumb_pos] + movzx ecx, word [gs:si + widget.x] ; Origine X par défaut + cmp byte [gs:si + widget.attr_mode], 2 + jne .do_sub + movzx ecx, word [gs:si + widget.y] ; Origine Y si vertical + .do_sub: + sub eax, ecx ; EAX = DeltaPix (pixels relatifs) + + ; Produit en croix : (DeltaPix * RangeLogique) / RangePix + movzx ecx, word [gs:si + widget.attr_max] + movzx edx, word [gs:si + widget.attr_min] + sub ecx, edx ; ECX = RangeLogique (Max - Min) + + mul ecx ; EAX = DeltaPix * RangeLogique + xor edx, edx ; Nettoyage EDX pour div 32 bits + div ebx ; EAX = Valeur métier relative + + ; Ajouter le Min métier et stocker + movzx edx, word [gs:si + widget.attr_min] + add eax, edx ; EAX = Valeur métier finale + mov [gs:si + widget.attr_val], ax ; Stockage (tronqué en 16 bits) + + .done: + pop edx + pop ecx + pop ebx + pop eax + ret + +; ----------------------------------------------------------------------------- +; gui_slider_update_pixels +; In: GS:SI = widget +; Calcule .thumb_pos (pixels) à partir de .attr_val (métier) +; ----------------------------------------------------------------------------- +gui_slider_update_pixels: + pushad ; Sauvegarde EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI + + ; Calculer la dimension totale du widget (W ou H) + movzx eax, word [gs:si + widget.w] + cmp byte [gs:si + widget.attr_mode], 2 ; Mode Vertical ? + jne .calc_range + movzx eax, word [gs:si + widget.h] + + .calc_range: + ; Calculer RangePix (Amplitude max du mouvement) + ; RangePix = DimensionTotale - (DimensionTotale * thumb_pct / 100) + push eax ; Sauvegarde DimTotale + movzx ebx, byte [gs:si + widget.thumb_pct] + mul ebx ; EAX = Dim * pct + mov ebx, 100 + xor edx, edx + div ebx ; EAX = Taille physique du thumb + + pop ebx ; EBX = DimTotale + sub ebx, eax ; EBX = RangePix (Amplitude) + jz .done ; Sécurité : si RangePix = 0 + + ; Calculer DeltaLogique (Progression métier) + movzx eax, word [gs:si + widget.attr_val] + movzx ecx, word [gs:si + widget.attr_min] + sub eax, ecx ; EAX = DeltaLogique (Val - Min) + js .set_min ; Sécurité si Val < Min + + ; Produit en croix : (DeltaLogique * RangePix) / RangeLogique + movzx ecx, word [gs:si + widget.attr_max] + movzx edx, word [gs:si + widget.attr_min] + sub ecx, edx ; ECX = RangeLogique (Max - Min) + jz .done ; Sécurité : RangeLogique ne peut être 0 + + mul ebx ; EAX = DeltaLogique * RangePix + xor edx, edx + div ecx ; EAX = Offset pixel relatif + + ; 5. Ajouter l'origine physique (X ou Y) + movzx edx, word [gs:si + widget.x] + cmp byte [gs:si + widget.attr_mode], 2 + jne .store + movzx edx, word [gs:si + widget.y] + .store: + add eax, edx ; EAX = Position pixel finale + mov [gs:si + widget.thumb_pos], ax + jmp .done + + .set_min: + ; Si la valeur est sous le minimum, on colle au début + movzx ax, word [gs:si + widget.x] + cmp byte [gs:si + widget.attr_mode], 2 + jne .force_store + movzx ax, word [gs:si + widget.y] + .force_store: + mov [gs:si + widget.thumb_pos], ax + + .done: + popad ; Restauration propre + ret + ; --- Logique spécifique Slider --- gui_logic_slider: test bl, 1 ; Bouton enfoncé ? @@ -735,7 +877,7 @@ gui_logic_slider: div bx ; AX = Thumb Width ; Check collision avec le thumb actuel - mov bx, [gs:si + widget.attr_val] + mov bx, [gs:si + widget.thumb_pos] cmp cx, bx jb .click_outside_h ; Click avant le thumb add bx, ax @@ -744,7 +886,7 @@ gui_logic_slider: ; Click DANS le thumb : Anchor = MouseX - AttrVal mov ax, cx - sub ax, [gs:si + widget.attr_val] + sub ax, [gs:si + widget.thumb_pos] mov [gs:si + widget.attr_anchor], ax jmp .init_done @@ -763,7 +905,7 @@ gui_logic_slider: div bx ; AX = Thumb Height ; Check collision avec le thumb actuel - mov bx, [gs:si + widget.attr_val] + mov bx, [gs:si + widget.thumb_pos] cmp dx, bx jb .click_outside_v add bx, ax @@ -772,7 +914,7 @@ gui_logic_slider: ; Click DANS le thumb mov ax, dx - sub ax, [gs:si + widget.attr_val] + sub ax, [gs:si + widget.thumb_pos] mov [gs:si + widget.attr_anchor], ax jmp .init_done @@ -867,9 +1009,9 @@ gui_logic_slider: mov ax, bx .apply_pos: - cmp ax, [gs:si + widget.attr_val] + cmp ax, [gs:si + widget.thumb_pos] je .no_change - mov [gs:si + widget.attr_val], ax + mov [gs:si + widget.thumb_pos], ax ; Appel du callback on_drag cmp word [gs:si + widget.event_drag], 0 @@ -905,7 +1047,7 @@ gui_logic_checkbox: jne .hover ; Clic validé ! Toggle value - xor word [gs:si + widget.attr_val], 1 + xor word [gs:si + widget.thumb_pos], 1 mov byte [gs:si + widget.oldstate], 255 ; Force redraw mov al, 1