memory + string
This commit is contained in:
parent
16865bb141
commit
182d8a36c3
7 changed files with 146 additions and 17 deletions
|
|
@ -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).
|
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
|
* [MEMORY MAP](/doc/MEMORY_MAP.md) : Plan de la mémoire
|
||||||
38
doc/API_MEMORY.md
Normal file
38
doc/API_MEMORY.md
Normal 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
|
||||||
|
|
@ -44,6 +44,7 @@ section .text
|
||||||
%include "./common/cursor.asm"
|
%include "./common/cursor.asm"
|
||||||
%include "./common/patterns.asm"
|
%include "./common/patterns.asm"
|
||||||
%include "./common/generic.asm"
|
%include "./common/generic.asm"
|
||||||
|
%include "./common/string.asm"
|
||||||
|
|
||||||
; definition du BDA
|
; definition du BDA
|
||||||
%include "./common/bda.asm"
|
%include "./common/bda.asm"
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
%define MEM_GET_SIZE 1
|
%define MEM_GET_SIZE 1
|
||||||
%define MEM_FREE 2
|
%define MEM_FREE 2
|
||||||
%define MEM_RESOLVE 3
|
%define MEM_RESOLVE 3
|
||||||
|
%define MEM_INIT 4
|
||||||
|
|
||||||
; --- Macro API ---
|
; --- Macro API ---
|
||||||
; Usage: MEM FUNCTION, [ARG1], [ARG2]...
|
; Usage: MEM FUNCTION, [ARG1], [ARG2]...
|
||||||
|
|
@ -41,9 +42,11 @@ mem_api_table:
|
||||||
dw mem_get_size
|
dw mem_get_size
|
||||||
dw mem_free
|
dw mem_free
|
||||||
dw mem_resolve
|
dw mem_resolve
|
||||||
|
dw mem_init
|
||||||
|
|
||||||
struc mem_block
|
struc mem_block
|
||||||
.status resb 1 ; État du bloc (0=Libre, 1=Occupé)
|
.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)
|
.size resw 1 ; Taille des données (sans le header)
|
||||||
.next resw 1 ; Offset du prochain bloc (0 = Fin)
|
.next resw 1 ; Offset du prochain bloc (0 = Fin)
|
||||||
endstruc
|
endstruc
|
||||||
|
|
@ -97,6 +100,12 @@ mem_alloc:
|
||||||
push es
|
push es
|
||||||
push di
|
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 .curr_ptr, 0 ; On commence la recherche à l'offset 0
|
||||||
|
|
||||||
mov ax, MEM_HEAP_SEG
|
mov ax, MEM_HEAP_SEG
|
||||||
|
|
@ -208,8 +217,6 @@ mem_free:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
push es
|
push es
|
||||||
push di
|
push di
|
||||||
push bx
|
push bx
|
||||||
|
|
@ -218,6 +225,10 @@ mem_free:
|
||||||
test ax, ax
|
test ax, ax
|
||||||
jz .done ; Sécurité Handle NULL
|
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 bx, MEM_HEAP_SEG
|
||||||
mov es, bx
|
mov es, bx
|
||||||
|
|
||||||
|
|
|
||||||
75
src/common/string.asm
Normal file
75
src/common/string.asm
Normal 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
|
||||||
|
|
@ -56,7 +56,8 @@ gui_draw_single_widget:
|
||||||
; Dispatch selon le type
|
; Dispatch selon le type
|
||||||
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
|
cmp byte [gs:si + widget.type], OBJ_TYPE_LABEL
|
||||||
jne .case_1
|
jne .case_1
|
||||||
jmp .done
|
call draw_label
|
||||||
|
jmp .done
|
||||||
|
|
||||||
.case_1:
|
.case_1:
|
||||||
cmp byte [gs:si + widget.type], OBJ_TYPE_SLIDER
|
cmp byte [gs:si + widget.type], OBJ_TYPE_SLIDER
|
||||||
|
|
@ -451,29 +452,31 @@ draw_checkbox:
|
||||||
GFX WRITE, dx, ax
|
GFX WRITE, dx, ax
|
||||||
|
|
||||||
ret
|
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
|
; affiche le texte au centre du widget gs:si
|
||||||
;
|
;
|
||||||
draw_text:
|
draw_text:
|
||||||
; Petit hack pour recentrer le texte après l'effet gras
|
; --- Centrage Texte ---
|
||||||
mov cx, [gs:si + widget.w]
|
|
||||||
mov dx, [gs:si + widget.h]
|
|
||||||
|
|
||||||
.text:
|
|
||||||
; --- Centrage Texte (Simplifié) ---
|
|
||||||
mov es, [gs:si + widget.text_seg]
|
mov es, [gs:si + widget.text_seg]
|
||||||
mov di, [gs:si + widget.text_ofs]
|
mov di, [gs:si + widget.text_ofs]
|
||||||
xor cx, cx
|
xor cx, cx
|
||||||
|
|
||||||
.strlen:
|
push di
|
||||||
cmp byte [es:di], 0
|
push es
|
||||||
je .calc
|
call strlen
|
||||||
inc cx
|
add sp, 4 ; Fix: Nettoyage de la pile (2 args * 2 octets)
|
||||||
inc di
|
|
||||||
jmp .strlen
|
|
||||||
|
|
||||||
.calc:
|
.calc:
|
||||||
shl cx, 3 ; Largeur texte px
|
shl cx, 3 ; Largeur texte px : x = strlen * 8
|
||||||
push ax ; Sauve X original
|
push ax ; Sauve X original
|
||||||
mov ax, [gs:si + widget.w]
|
mov ax, [gs:si + widget.w]
|
||||||
sub ax, cx
|
sub ax, cx
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue