memory + string

This commit is contained in:
Frater 2026-02-10 16:16:55 +01:00
commit 182d8a36c3
7 changed files with 146 additions and 17 deletions

View file

@ -4,6 +4,7 @@ Le système utilise plusieurs macro *GFX*,*GUI*, etc pour appeler les fonctions
Les arguments sont passés sur la pile (Convention C : dernier argument empilé en premier, nettoyage par l'appelant géré par la macro).
* [CGA](/doc/CGA.md) : controleur graphique CGA
* [CGA](/doc/API_CGA.md) : controleur graphique CGA
* [MEMORY](/doc/API_MEMORY.md) : controleur graphique CGA
* [MEMORY MAP](/doc/MEMORY_MAP.md) : Plan de la mémoire

38
doc/API_MEMORY.md Normal file
View file

@ -0,0 +1,38 @@
# API Gestionnaire de Mémoire (Heap)
## Description
Ce module fournit un gestionnaire de mémoire dynamique (Heap) simple pour le mode réel x86. Il utilise un algorithme **First-Fit** avec fusion des blocs libres (coalescing) lors de l'allocation pour minimiser la fragmentation.
Le segment de mémoire utilisé est défini par `MEM_HEAP_SEG` (par défaut `0x2000`, soit l'adresse physique `0x20000`).
## Structure des Données
Chaque bloc mémoire est précédé d'un en-tête de 6 octets (aligné sur 16 bits) :
| Offset | Taille | Champ | Description |
| :--- | :--- | :--- | :--- |
| +0 | 1 octet | Status | `0` = Libre, `1` = Alloué |
| +1 | 1 octet | Padding | Réservé pour l'alignement |
| +2 | 2 octets | Size | Taille des données utiles (en octets) |
| +4 | 2 octets | Next | Offset du prochain bloc (0 = Fin de liste) |
| +6 | ... | Data | Données utilisateur |
## Utilisation
L'interaction se fait principalement via la macro `MEM`.
```nasm
%include "./common/memory.asm"
; Initialisation (Obligatoire au démarrage)
MEM MEM_INIT
; Allocation de 100 octets
MEM MEM_ALLOC, 100
; AX contient le handle (offset) ou 0 si erreur
; Utilisation du pointeur
mov bx, ax ; Sauvegarde du handle
MEM MEM_RESOLVE, bx
; ES:DI pointe maintenant vers les données
; Libération
MEM MEM_FREE, bx

View file

@ -44,6 +44,7 @@ section .text
%include "./common/cursor.asm"
%include "./common/patterns.asm"
%include "./common/generic.asm"
%include "./common/string.asm"
; definition du BDA
%include "./common/bda.asm"

View file

@ -23,6 +23,7 @@
%define MEM_GET_SIZE 1
%define MEM_FREE 2
%define MEM_RESOLVE 3
%define MEM_INIT 4
; --- Macro API ---
; Usage: MEM FUNCTION, [ARG1], [ARG2]...
@ -41,9 +42,11 @@ mem_api_table:
dw mem_get_size
dw mem_free
dw mem_resolve
dw mem_init
struc mem_block
.status resb 1 ; État du bloc (0=Libre, 1=Occupé)
.pad resb 1 ; Padding pour alignement 16-bits
.size resw 1 ; Taille des données (sans le header)
.next resw 1 ; Offset du prochain bloc (0 = Fin)
endstruc
@ -97,6 +100,12 @@ mem_alloc:
push es
push di
; Alignement de la taille demandée sur 2 octets (Word align)
mov ax, .size_requested
test ax, 1
jz .size_aligned
inc word .size_requested
.size_aligned:
mov .curr_ptr, 0 ; On commence la recherche à l'offset 0
mov ax, MEM_HEAP_SEG
@ -208,8 +217,6 @@ mem_free:
push bp
mov bp, sp
push es
push di
push bx
@ -218,6 +225,10 @@ mem_free:
test ax, ax
jz .done ; Sécurité Handle NULL
; Sécurité : Vérifier si le handle est dans le segment
cmp ax, MEM_HEAP_SIZE
ja .done
mov bx, MEM_HEAP_SEG
mov es, bx

75
src/common/string.asm Normal file
View file

@ -0,0 +1,75 @@
; -----------------------------------------------------------------------------
; strcpy
; Copie une chaine ASCIIZ
; -----------------------------------------------------------------------------
%define .dest_seg word [bp+4]
%define .dest_ofs word [bp+6]
%define .src_seg word [bp+8]
%define .src_ofs word [bp+10]
strcpy:
push bp
mov bp, sp
push ds
push es
push si
push di
mov ax, .src_seg
mov ds, ax
mov si, .src_ofs
mov ax, .dest_seg
mov es, ax
mov di, .dest_ofs
.loop:
lodsb
stosb
test al, al
jnz .loop
pop di
pop si
pop es
pop ds
leave
ret
%undef .dest_seg
%undef .dest_ofs
%undef .src_seg
%undef .src_ofs
; -----------------------------------------------------------------------------
; strlen
; Calcule la longueur d'une chaine [es:di]
; Out: CX = Length
; -----------------------------------------------------------------------------
%define .str_seg word [bp+4]
%define .str_ofs word [bp+6]
strlen:
push bp
mov bp, sp
push ax
push es
push di
xor cx, cx
mov ax, .str_seg
mov es, ax
mov di, .str_ofs
.loop:
cmp byte [es:di], 0
je .done
inc cx
inc di
jmp .loop
.done:
pop di
pop es
pop ax
leave
ret
%undef .str_seg
%undef .str_ofs

View file

@ -56,7 +56,8 @@ gui_draw_single_widget:
; Dispatch selon le type
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
jne .case_1
jmp .done
call draw_label
jmp .done
.case_1:
cmp byte [gs:si + widget.type], OBJ_TYPE_SLIDER
@ -451,29 +452,31 @@ draw_checkbox:
GFX WRITE, dx, ax
ret
;
; dessine un label (texte simple)
;
draw_label:
GFX TXT_MODE, GFX_TXT_BLACK_TRANSPARENT
call draw_text
ret
;
; affiche le texte au centre du widget gs:si
;
draw_text:
; Petit hack pour recentrer le texte après l'effet gras
mov cx, [gs:si + widget.w]
mov dx, [gs:si + widget.h]
.text:
; --- Centrage Texte (Simplifié) ---
; --- Centrage Texte ---
mov es, [gs:si + widget.text_seg]
mov di, [gs:si + widget.text_ofs]
xor cx, cx
.strlen:
cmp byte [es:di], 0
je .calc
inc cx
inc di
jmp .strlen
push di
push es
call strlen
add sp, 4 ; Fix: Nettoyage de la pile (2 args * 2 octets)
.calc:
shl cx, 3 ; Largeur texte px
shl cx, 3 ; Largeur texte px : x = strlen * 8
push ax ; Sauve X original
mov ax, [gs:si + widget.w]
sub ax, cx