fix memory map doc
This commit is contained in:
parent
4b62e01e82
commit
24a59171e5
3 changed files with 179 additions and 176 deletions
|
|
@ -11,10 +11,10 @@ The processor starts in Real Mode, addressing 1 MB of memory.
|
||||||
| **`0x00000`** | **`0x003FF`** | 1 KB | **IVT** (Interrupt Vector Table) | `0x0000` | `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` |
|
| **`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`** | **`0x07FFF`** | 30.5 KB | **Free** (Low Memory) | | |
|
| **`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` |
|
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `memory.asm` |
|
||||||
| **`0x18000`** | **`0x18FFF`** | ~4 KB | **GUI RAM** (Widget Allocation) | `0x0A00` | `gui/lib.asm` |
|
| **`0x18000`** | **`0x9FBFF`** | 543 KB | **Free** (Conventional RAM) | | |
|
||||||
| **`0x19000`** | **`0x9FBFF`** | 539 KB | **Free** (Conventional RAM) | | |
|
|
||||||
| **`0x9FC00`** | **`0x9FFFF`** | 1 KB | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` |
|
| **`0x9FC00`** | **`0x9FFFF`** | 1 KB | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` |
|
||||||
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
| **`0xA0000`** | **`0xAFFFF`** | 64 KB | **VGA RAM** (Graphics Modes) | `0xA000` | `Hardware` |
|
||||||
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
| **`0xB0000`** | **`0xB7FFF`** | 32 KB | **MDA RAM** (Monochrome Text) | `0xB000` | `Hardware` |
|
||||||
|
|
@ -42,8 +42,8 @@ The project separates the standard IBM BDA from its own variables to avoid confl
|
||||||
|
|
||||||
#### Stack & GUI RAM
|
#### Stack & GUI RAM
|
||||||
* **Stack**: Segment `0x0800`, SP `0xFFFE`. Grows downwards from physical address `0x17FFE`.
|
* **Stack**: Segment `0x0800`, SP `0xFFFE`. Grows downwards from physical address `0x17FFE`.
|
||||||
* **GUI RAM**: Segment `0x0A00` (Physical `0x0A000`).
|
* **GUI RAM**: Segment `0x0060` (Physical `0x00600`).
|
||||||
* **Layout**: The GUI RAM sits at the "bottom" of the stack segment's physical range, but since the stack starts at the top (`0x17FFE`) and grows down, there is approximately **56 KB** of safe space before collision.
|
* **Layout**: Located in low memory (`0x00600`) to avoid any collision with the Stack (`0x08000`).
|
||||||
|
|
||||||
#### Video RAM (CGA High-Res)
|
#### Video RAM (CGA High-Res)
|
||||||
* **Segment**: `0xB800`
|
* **Segment**: `0xB800`
|
||||||
|
|
@ -73,10 +73,10 @@ Le processeur démarre en mode réel, adressant 1 Mo de mémoire.
|
||||||
| **`0x00000`** | **`0x003FF`** | 1 Ko | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
| **`0x00000`** | **`0x003FF`** | 1 Ko | **IVT** (Interrupt Vector Table) | `0x0000` | `memory.asm` |
|
||||||
| **`0x00400`** | **`0x004FF`** | 256 o | **BDA** (BIOS Data Area) Standard | `0x0040` | `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` |
|
| **`0x00500`** | **`0x005FF`** | ~256 o | **Custom BDA** (Données Drivers) | `0x0050` | `memory.asm` |
|
||||||
| **`0x00600`** | **`0x07FFF`** | 30.5 Ko | **Libre** (Mémoire Basse) | | |
|
| **`0x00600`** | **`0x00AFF`** | 1.25 Ko | **GUI RAM** (Allocation Widgets) | `0x0060` | `gui/lib.asm` |
|
||||||
| **`0x08000`** | **`0x17FFF`** | 64 KB | **Stack** (Grows downwards) | `0x0800` | `memory.asm` |
|
| **`0x00B00`** | **`0x07FFF`** | 29 Ko | **Libre** (Mémoire Basse) | | |
|
||||||
| **`0x18000`** | **`0x18FFF`** | ~4 KB | **GUI RAM** (Widget Allocation) | `0x0A00` | `gui/lib.asm` |
|
| **`0x08000`** | **`0x17FFF`** | 64 Ko | **Pile** (Stack) | `0x0800` | `memory.asm` |
|
||||||
| **`0x19000`** | **`0x9FBFF`** | 539 Ko | **Libre** (RAM Conventionnelle) | | |
|
| **`0x18000`** | **`0x9FBFF`** | 543 Ko | **Libre** (RAM Conventionnelle) | | |
|
||||||
| **`0x9FC00`** | **`0x9FFFF`** | 1 Ko | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` |
|
| **`0x9FC00`** | **`0x9FFFF`** | 1 Ko | **EBDA** (Extended BIOS Data Area) | `0x9FC0` | `memory.asm` |
|
||||||
| **`0xA0000`** | **`0xAFFFF`** | 64 Ko | **VGA RAM** (Modes Graphiques) | `0xA000` | `Matériel` |
|
| **`0xA0000`** | **`0xAFFFF`** | 64 Ko | **VGA RAM** (Modes Graphiques) | `0xA000` | `Matériel` |
|
||||||
| **`0xB0000`** | **`0xB7FFF`** | 32 Ko | **MDA RAM** (Texte Monochrome) | `0xB000` | `Matériel` |
|
| **`0xB0000`** | **`0xB7FFF`** | 32 Ko | **MDA RAM** (Texte Monochrome) | `0xB000` | `Matériel` |
|
||||||
|
|
@ -104,8 +104,8 @@ Le projet sépare la BDA standard IBM de ses propres variables pour éviter les
|
||||||
|
|
||||||
#### Stack & GUI RAM
|
#### Stack & GUI RAM
|
||||||
* **Stack** : Segment `0x0800`, SP `0xFFFE`. Grandit vers le bas depuis l'adresse physique `0x17FFE`.
|
* **Stack** : Segment `0x0800`, SP `0xFFFE`. Grandit vers le bas depuis l'adresse physique `0x17FFE`.
|
||||||
* **GUI RAM** : Segment `0x0A00` (Physique `0x0A000`).
|
* **GUI RAM** : Segment `0x0060` (Physique `0x00600`).
|
||||||
* **Organisation** : La RAM GUI se trouve "en bas" de la plage physique du segment de pile, mais comme la pile commence tout en haut (`0x17FFE`) et descend, il y a environ **56 Ko** d'espace libre avant collision.
|
* **Organisation** : Située en mémoire basse (`0x00600`) pour éviter toute collision avec la Pile (`0x08000`).
|
||||||
|
|
||||||
#### Video RAM (CGA High-Res)
|
#### Video RAM (CGA High-Res)
|
||||||
* **Segment** : `0xB800`
|
* **Segment** : `0xB800`
|
||||||
|
|
|
||||||
|
|
@ -27,25 +27,25 @@
|
||||||
; --- Macro API ---
|
; --- Macro API ---
|
||||||
; Usage: MEM FUNCTION, [ARG1], [ARG2]...
|
; Usage: MEM FUNCTION, [ARG1], [ARG2]...
|
||||||
%macro MEM 1-*
|
%macro MEM 1-*
|
||||||
%rep %0 - 1
|
%rep %0 - 1
|
||||||
%rotate -1
|
%rotate -1
|
||||||
push %1
|
push %1
|
||||||
%endrep
|
%endrep
|
||||||
%rotate -1
|
%rotate -1
|
||||||
call word [cs:mem_api_table + ((%1)*2)]
|
call word [cs:mem_api_table + ((%1)*2)]
|
||||||
add sp, (%0 - 1) * 2
|
add sp, (%0 - 1) * 2
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
mem_api_table:
|
mem_api_table:
|
||||||
dw mem_alloc
|
dw mem_alloc
|
||||||
dw mem_get_size
|
dw mem_get_size
|
||||||
dw mem_free
|
dw mem_free
|
||||||
dw mem_resolve
|
dw mem_resolve
|
||||||
|
|
||||||
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é)
|
||||||
.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
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
|
@ -54,28 +54,28 @@ endstruc
|
||||||
; Crée un seul gros bloc libre couvrant tout le segment.
|
; Crée un seul gros bloc libre couvrant tout le segment.
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
mem_init:
|
mem_init:
|
||||||
push ax
|
push ax
|
||||||
push es
|
push es
|
||||||
push di
|
push di
|
||||||
|
|
||||||
mov ax, MEM_HEAP_SEG
|
mov ax, MEM_HEAP_SEG
|
||||||
mov es, ax
|
mov es, ax
|
||||||
xor di, di
|
xor di, di
|
||||||
|
|
||||||
; Initialisation du premier bloc (Header)
|
; Initialisation du premier bloc (Header)
|
||||||
mov byte [es:di + mem_block.status], MEM_STATUS_FREE
|
mov byte [es:di + mem_block.status], MEM_STATUS_FREE
|
||||||
|
|
||||||
; Taille disponible = Total - TailleHeader
|
; Taille disponible = Total - TailleHeader
|
||||||
mov ax, MEM_HEAP_SIZE
|
mov ax, MEM_HEAP_SIZE
|
||||||
sub ax, mem_block_size
|
sub ax, mem_block_size
|
||||||
mov word [es:di + mem_block.size], ax
|
mov word [es:di + mem_block.size], ax
|
||||||
|
|
||||||
mov word [es:di + mem_block.next], 0
|
mov word [es:di + mem_block.next], 0
|
||||||
|
|
||||||
pop di
|
pop di
|
||||||
pop es
|
pop es
|
||||||
pop ax
|
pop ax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; mem_alloc
|
; mem_alloc
|
||||||
|
|
@ -84,156 +84,157 @@ mem_init:
|
||||||
; Stack: [BP+4] = Taille demandée (word)
|
; Stack: [BP+4] = Taille demandée (word)
|
||||||
; Output: AX = Handle (Offset du bloc de données) ou 0 si échec
|
; Output: AX = Handle (Offset du bloc de données) ou 0 si échec
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .size_requested word [bp+4]
|
||||||
|
; variables
|
||||||
|
%define .curr_ptr word [bp-2]
|
||||||
mem_alloc:
|
mem_alloc:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
sub sp, 2
|
sub sp, 2
|
||||||
|
|
||||||
%define .curr_ptr word [bp-2]
|
push bx
|
||||||
%define .size_requested word [bp+4]
|
push cx
|
||||||
|
push es
|
||||||
|
push di
|
||||||
|
|
||||||
push bx
|
mov .curr_ptr, 0 ; On commence la recherche à l'offset 0
|
||||||
push cx
|
|
||||||
push es
|
|
||||||
push di
|
|
||||||
|
|
||||||
mov .curr_ptr, 0 ; On commence la recherche à l'offset 0
|
mov ax, MEM_HEAP_SEG
|
||||||
|
mov es, ax
|
||||||
mov ax, MEM_HEAP_SEG
|
|
||||||
mov es, ax
|
|
||||||
|
|
||||||
.scan_loop:
|
.scan_loop:
|
||||||
mov di, .curr_ptr ; DI = Ptr courant
|
mov di, .curr_ptr ; DI = Ptr courant
|
||||||
|
|
||||||
; 1. Le bloc est-il LIBRE ?
|
; 1. Le bloc est-il LIBRE ?
|
||||||
cmp byte [es:di + mem_block.status], MEM_STATUS_FREE
|
cmp byte [es:di + mem_block.status], MEM_STATUS_FREE
|
||||||
jne .next_block
|
jne .next_block
|
||||||
|
|
||||||
; 2. Tentative de FUSION (Coalescing) avec les blocs suivants
|
; 2. Tentative de FUSION (Coalescing) avec les blocs suivants
|
||||||
.try_merge:
|
.try_merge:
|
||||||
mov bx, [es:di + mem_block.next]
|
mov bx, [es:di + mem_block.next]
|
||||||
cmp bx, 0
|
cmp bx, 0
|
||||||
je .check_size ; Pas de suivant, on vérifie la taille
|
je .check_size ; Pas de suivant, on vérifie la taille
|
||||||
|
|
||||||
; Si le suivant est aussi libre, on fusionne
|
; Si le suivant est aussi libre, on fusionne
|
||||||
cmp byte [es:bx + mem_block.status], MEM_STATUS_FREE
|
cmp byte [es:bx + mem_block.status], MEM_STATUS_FREE
|
||||||
jne .check_size
|
jne .check_size
|
||||||
|
|
||||||
; Nouvelle Taille = TailleActuelle + Header + TailleSuivant
|
; Nouvelle Taille = TailleActuelle + Header + TailleSuivant
|
||||||
mov ax, [es:bx + mem_block.size]
|
mov ax, [es:bx + mem_block.size]
|
||||||
add ax, mem_block_size
|
add ax, mem_block_size
|
||||||
add [es:di + mem_block.size], ax
|
add [es:di + mem_block.size], ax
|
||||||
|
|
||||||
; Mise à jour du chainage (saute le bloc fusionné)
|
; Mise à jour du chainage (saute le bloc fusionné)
|
||||||
mov ax, [es:bx + mem_block.next]
|
mov ax, [es:bx + mem_block.next]
|
||||||
mov [es:di + mem_block.next], ax
|
mov [es:di + mem_block.next], ax
|
||||||
|
|
||||||
jmp .try_merge ; On boucle pour voir si le suivant du suivant est libre
|
jmp .try_merge ; On boucle pour voir si le suivant du suivant est libre
|
||||||
|
|
||||||
.check_size:
|
.check_size:
|
||||||
; 3. Vérifier si la taille est suffisante
|
; 3. Vérifier si la taille est suffisante
|
||||||
mov ax, .size_requested ; Taille demandée (Argument)
|
mov ax, .size_requested ; Taille demandée (Argument)
|
||||||
cmp [es:di + mem_block.size], ax
|
cmp [es:di + mem_block.size], ax
|
||||||
jb .next_block ; Trop petit
|
jb .next_block ; Trop petit
|
||||||
|
|
||||||
; 4. Allocation (Split si possible)
|
; 4. Allocation (Split si possible)
|
||||||
; Calculer l'espace restant
|
; Calculer l'espace restant
|
||||||
mov cx, [es:di + mem_block.size]
|
mov cx, [es:di + mem_block.size]
|
||||||
sub cx, ax ; CX = Reste
|
sub cx, ax ; CX = Reste
|
||||||
|
|
||||||
; Peut-on créer un nouveau bloc dans le reste ? (Header + au moins 1 octet)
|
; Peut-on créer un nouveau bloc dans le reste ? (Header + au moins 1 octet)
|
||||||
cmp cx, mem_block_size + 1
|
cmp cx, mem_block_size + 1
|
||||||
jb .allocate_full
|
jb .allocate_full
|
||||||
|
|
||||||
; --- SPLIT ---
|
; --- SPLIT ---
|
||||||
; Marquer le bloc actuel comme utilisé avec la taille demandée
|
; Marquer le bloc actuel comme utilisé avec la taille demandée
|
||||||
mov byte [es:di + mem_block.status], MEM_STATUS_USED
|
mov byte [es:di + mem_block.status], MEM_STATUS_USED
|
||||||
mov [es:di + mem_block.size], ax
|
mov [es:di + mem_block.size], ax
|
||||||
|
|
||||||
; Créer le nouveau header dans l'espace restant
|
; Créer le nouveau header dans l'espace restant
|
||||||
mov bx, di
|
mov bx, di
|
||||||
add bx, mem_block_size
|
add bx, mem_block_size
|
||||||
add bx, ax ; BX = Offset du nouveau bloc
|
add bx, ax ; BX = Offset du nouveau bloc
|
||||||
|
|
||||||
mov byte [es:bx + mem_block.status], MEM_STATUS_FREE
|
mov byte [es:bx + mem_block.status], MEM_STATUS_FREE
|
||||||
|
|
||||||
sub cx, mem_block_size ; Taille utile du nouveau bloc
|
sub cx, mem_block_size ; Taille utile du nouveau bloc
|
||||||
mov [es:bx + mem_block.size], cx
|
mov [es:bx + mem_block.size], cx
|
||||||
|
|
||||||
; Insérer dans la liste chainée
|
; Insérer dans la liste chainée
|
||||||
mov dx, [es:di + mem_block.next]
|
mov dx, [es:di + mem_block.next]
|
||||||
mov [es:bx + mem_block.next], dx
|
mov [es:bx + mem_block.next], dx
|
||||||
mov [es:di + mem_block.next], bx
|
mov [es:di + mem_block.next], bx
|
||||||
|
|
||||||
jmp .success
|
jmp .success
|
||||||
|
|
||||||
.allocate_full:
|
.allocate_full:
|
||||||
; On prend tout le bloc sans le couper
|
; On prend tout le bloc sans le couper
|
||||||
mov byte [es:di + mem_block.status], MEM_STATUS_USED
|
mov byte [es:di + mem_block.status], MEM_STATUS_USED
|
||||||
|
|
||||||
.success:
|
.success:
|
||||||
; Retourner le handle (Offset des DONNÉES = DI + Header)
|
; Retourner le handle (Offset des DONNÉES = DI + Header)
|
||||||
mov ax, di
|
mov ax, di
|
||||||
add ax, mem_block_size
|
add ax, mem_block_size
|
||||||
jmp .done
|
jmp .done
|
||||||
|
|
||||||
.next_block:
|
.next_block:
|
||||||
; Passer au bloc suivant
|
; Passer au bloc suivant
|
||||||
mov di, .curr_ptr
|
mov di, .curr_ptr
|
||||||
mov ax, [es:di + mem_block.next]
|
mov ax, [es:di + mem_block.next]
|
||||||
mov .curr_ptr, ax
|
mov .curr_ptr, ax
|
||||||
cmp ax, 0
|
cmp ax, 0
|
||||||
jne .scan_loop
|
jne .scan_loop
|
||||||
|
|
||||||
; Échec : Plus de mémoire ou fragmentation trop élevée
|
; Échec : Plus de mémoire ou fragmentation trop élevée
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
pop di
|
pop di
|
||||||
pop es
|
pop es
|
||||||
pop cx
|
pop cx
|
||||||
pop bx
|
pop bx
|
||||||
%undef .curr_ptr
|
leave ; Restaure SP et BP
|
||||||
%undef .size_requested
|
ret
|
||||||
leave ; Restaure SP et BP
|
%undef .curr_ptr
|
||||||
ret
|
%undef .size_requested
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; mem_free
|
; mem_free
|
||||||
; Libère un bloc mémoire.
|
; Libère un bloc mémoire.
|
||||||
; Stack: [BP+4] = Handle (word)
|
; Stack: [BP+4] = Handle (word)
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .handle word [bp+4]
|
||||||
mem_free:
|
mem_free:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
%define .handle word [bp+4]
|
|
||||||
|
|
||||||
push es
|
|
||||||
push di
|
|
||||||
push bx
|
|
||||||
|
|
||||||
mov ax, .handle ; Handle
|
push es
|
||||||
test ax, ax
|
push di
|
||||||
jz .done ; Sécurité Handle NULL
|
push bx
|
||||||
|
|
||||||
mov bx, MEM_HEAP_SEG
|
mov ax, .handle ; Handle
|
||||||
mov es, bx
|
test ax, ax
|
||||||
|
jz .done ; Sécurité Handle NULL
|
||||||
|
|
||||||
; Retrouver le header (Handle - HeaderSize)
|
mov bx, MEM_HEAP_SEG
|
||||||
mov di, ax
|
mov es, bx
|
||||||
sub di, mem_block_size
|
|
||||||
|
|
||||||
; Marquer simplement comme libre (le coalescing se fera au prochain alloc)
|
; Retrouver le header (Handle - HeaderSize)
|
||||||
mov byte [es:di + mem_block.status], MEM_STATUS_FREE
|
mov di, ax
|
||||||
|
sub di, mem_block_size
|
||||||
|
|
||||||
|
; Marquer simplement comme libre (le coalescing se fera au prochain alloc)
|
||||||
|
mov byte [es:di + mem_block.status], MEM_STATUS_FREE
|
||||||
|
|
||||||
.done:
|
.done:
|
||||||
pop bx
|
pop bx
|
||||||
pop di
|
pop di
|
||||||
pop es
|
pop es
|
||||||
%undef .handle
|
leave
|
||||||
leave
|
ret
|
||||||
ret
|
%undef .handle
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; mem_get_size
|
; mem_get_size
|
||||||
|
|
@ -241,36 +242,35 @@ mem_free:
|
||||||
; Stack: [BP+4] = Handle (word)
|
; Stack: [BP+4] = Handle (word)
|
||||||
; Output: AX = Taille
|
; Output: AX = Taille
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .handle word [bp+4]
|
||||||
mem_get_size:
|
mem_get_size:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
%define .handle word [bp+4]
|
push es
|
||||||
|
push di
|
||||||
|
|
||||||
push es
|
mov ax, .handle ; Handle
|
||||||
push di
|
test ax, ax
|
||||||
|
jz .error
|
||||||
|
|
||||||
mov ax, .handle ; Handle
|
mov bx, MEM_HEAP_SEG
|
||||||
test ax, ax
|
mov es, bx
|
||||||
jz .error
|
|
||||||
|
|
||||||
mov bx, MEM_HEAP_SEG
|
mov di, ax
|
||||||
mov es, bx
|
sub di, mem_block_size
|
||||||
|
|
||||||
mov di, ax
|
mov ax, [es:di + mem_block.size]
|
||||||
sub di, mem_block_size
|
jmp .done
|
||||||
|
|
||||||
mov ax, [es:di + mem_block.size]
|
|
||||||
jmp .done
|
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
.done:
|
.done:
|
||||||
pop di
|
pop di
|
||||||
pop es
|
pop es
|
||||||
%undef .handle
|
leave
|
||||||
leave
|
ret
|
||||||
ret
|
%undef .handle
|
||||||
|
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
; mem_resolve
|
; mem_resolve
|
||||||
|
|
@ -279,16 +279,18 @@ mem_get_size:
|
||||||
; Output: DX:AX = Segment:Offset
|
; Output: DX:AX = Segment:Offset
|
||||||
; ES:DI = Segment:Offset (pour utilisation immédiate avec stos/movs)
|
; ES:DI = Segment:Offset (pour utilisation immédiate avec stos/movs)
|
||||||
; -----------------------------------------------------------------------------
|
; -----------------------------------------------------------------------------
|
||||||
|
%define .handle word [bp+4]
|
||||||
mem_resolve:
|
mem_resolve:
|
||||||
push bp
|
push bp
|
||||||
mov bp, sp
|
mov bp, sp
|
||||||
|
|
||||||
mov ax, [bp+4] ; Handle
|
mov ax, .handle ; Handle
|
||||||
mov dx, MEM_HEAP_SEG
|
mov dx, MEM_HEAP_SEG
|
||||||
mov es, dx
|
mov es, dx
|
||||||
mov di, ax ; L'offset est le handle lui-même
|
mov di, ax ; L'offset est le handle lui-même
|
||||||
|
|
||||||
; DX contient déjà le segment, AX contient déjà l'offset
|
; DX contient déjà le segment, AX contient déjà l'offset
|
||||||
|
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
|
%undef .handle
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
; =============================================================================
|
; =============================================================================
|
||||||
|
|
||||||
; --- Configuration ---
|
; --- Configuration ---
|
||||||
%define GUI_RAM_SEG 0x1800 ; Segment de données UI (Safe: après Stack, avant Heap)
|
%define GUI_RAM_SEG 0x0600 ; Segment de données UI (Safe: après Stack, avant Heap)
|
||||||
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
|
%define GUI_MAX_WIDGETS 32 ; Nombre max de widgets simultanés
|
||||||
|
|
||||||
; Dimensions
|
; Dimensions
|
||||||
|
|
@ -94,6 +94,7 @@ struc widget
|
||||||
|
|
||||||
alignb 2 ; Alignement mémoire pour performance
|
alignb 2 ; Alignement mémoire pour performance
|
||||||
endstruc
|
endstruc
|
||||||
|
; actuellement 34 octets
|
||||||
|
|
||||||
%macro GUI 1-*
|
%macro GUI 1-*
|
||||||
%rep %0 - 1
|
%rep %0 - 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue