add memory lib + maps

This commit is contained in:
Frater 2026-02-07 16:03:29 +01:00
commit 4b62e01e82
10 changed files with 521 additions and 411 deletions

View file

@ -106,29 +106,6 @@ graph_driver:
dw cga_mouse_show ; déplacement du curseur
dw cga_mouse_cursor_move ; déplacement du curseur
; =============================================================================
; SECTION : PATTERNS & FILL
; https://paulsmith.github.io/classic-mac-patterns/
; =============================================================================
;
; pattern ID
%define PATTERN_BLACK 0
%define PATTERN_GRAY_DARK 1
%define PATTERN_GRAY_MID 2
%define PATTERN_GRAY_LIGHT 3
%define PATTERN_WHITE_LIGHT 4
%define PATTERN_WHITE 5
align 8
pattern_8x8:
dq 0x0000000000000000 ; pattern_black (Tout à 0 = Noir)
dq 0x2200880022008800 ; pattern_gray_dark (Majorité de 0)
dq 0x2288228822882288 ; pattern_gray_mid
dq 0xAA55AA55AA55AA55 ; pattern_gray_light (50/50)
dq 0x77DD77DD77DD77DD ; pattern_white_light (Majorité de 1 = Clair)
dq 0xFFFFFFFFFFFFFFFF ; pattern_white (Tout à 1 = Blanc)
; ------------------------------------------------------------
; initialise le mode graphique (via l'int 10h)
;

View file

@ -1,196 +0,0 @@
; =======================
; API
; =======================
%define MEM_INIT 0
%define MEM_DETECT 2
%define MEM_ALLOC 4
%define MEM_FREE 6
%define MEM_DUMP_RESET 8
%define MEM_DUMP_NEXT 10
memory_api:
dw mem_init
dw mem_detect
dw mem_alloc
dw mem_free
dw mem_dump_reset
dw mem_dump_next
; =======================
; Contexte en RAM (DS = CTX_SEG)
; =======================
heap_seg dw 0
heap_start dw 0
heap_end dw 0
free_head dw 0
dump_cursor dw 0
; =======================
; Constantes
; =======================
%define HDR_SIZE 8
%define FTR_SIZE 2
%define MIN_BLK 12 ; aligné (>= HDR+FTR)
%define FLAG_USED 1
%define MEM_SEG_DEB 0x0800 ; 0x0800:0000 = 0x8000 (32KB) évite IVT/BDA + stack 7C00
%define MEM_SEG_END 0xA000 ; 0xA000:0000 = 0xA0000 (début zone vidéo)
%define MEM_SEG_STEP 0x0040 ; 1KB = 0x400 bytes = 0x40 paragraphs
; ---------------------------------------------------------------------------
; Détection RAM conventionnelle
; Teste la RAM de MEM_SEG_DEB -> MEM_SEG_END (0xA000, 640KB), par pas de 1KB.
; Méthode: sauvegarde 1 mot, écrit 2 patterns, relit, restaure.
;
; Résultats:
; AX = taille détectée en Ko (KB) à partir de 0 jusqu’au “top conventionnel”
; DX = top_segment (segment du premier Ko NON valide) (optionnel)
;
; Précautions:
; - Ne testez PAS une zone où se trouve votre pile / variables.
; - Si votre pile est à 0000:7C00 (phys 0x7C00), commencez au moins à 0x0800.
; - Ne testez pas au-delà de MEM_SEG_END (0xA000: début VGA/vidéo).
; ---------------------------------------------------------------------------
memory_setup:
xor ax, ax ; AX = compteur KB trouvés
mov dx, MEM_SEG_DEB ; DX = segment courant testé
mov cx, MEM_SEG_END ; CX = segment fin (exclu)
xor di, di ; tester au début du bloc 1KB: ES:0000
.loop_seg:
cmp dx, cx
jae .done
mov es, dx
; sauvegarder le mot existant
mov bx, [es:di]
; pattern 1
mov word [es:di], 0x55AA
cmp word [es:di], 0x55AA
jne .fail_restore
; pattern 2 (inverse)
mov word [es:di], 0xAA55
cmp word [es:di], 0xAA55
jne .fail_restore
; restaurer
mov [es:di], bx
; OK: avancer d’1KB
inc ax ; +1KB valide
add dx, MEM_SEG_STEP
jmp .loop_seg
.fail_restore:
; restaurer avant de sortir
mov [es:di], bx
.done:
; AX contient le nb de KB valides *à partir de MEM_SEG_DEB*.
; Si vous voulez une taille “depuis 0KB”, ajoutez MEM_SEG_DEB*16/1024 = MEM_SEG_DEB/64.
;
; base_kb = MEM_SEG_DEB / 0x0040 (car 1KB = 0x40 segments)
mov bx, MEM_SEG_DEB
shr bx, 6 ; /64 = /0x40 => KB de base
add ax, bx ; AX = taille conventionnelle totale en KB (approx. 0..640)
; DX = segment du premier bloc NON valide (top)
; DX est déjà positionné (segment courant)
; stocker l'information dans le BDA
mov bx, BDA_SEGMENT
mov ds, bx
mov [BDA_INFO_MEM_SIZE], ax
mov [BDA_INFO_MEM_SEG], dx
ret
; -----------------------
; mem_detect
; AX=conv_kb, DX=ebda_seg, CF=0
; -----------------------
mem_detect:
push ds
xor ax, ax
int 12h ; AX = KiB conventionnelle
mov bx, ax ; conv_kb -> BX
; Lire EBDA segment depuis BDA:040Eh
; On suppose DS peut être changé temporairement
mov ax, 0x0040
mov ds, ax
mov dx, [0x000E] ; EBDA segment (souvent 0x9FC0 etc), 0 si absent
pop ds
mov ax, bx ; AX=conv_kb
clc
ret
; -----------------------
; mem_init
; Entrée (proposée) :
; AX = HEAP_SEG (0 => auto)
; BX = heap_start_offset (0 => défaut 0x0200)
; Sortie:
; CF=0 ok, CF=1 err
; -----------------------
mem_init:
; 1) déterminer heap_seg et heap_end en évitant EBDA
; 2) créer 1 seul bloc libre [heap_start..heap_end)
; Implémentation typique:
; - si AX=0 : choisir un segment RAM “safe” (ex: 0x7000) OU segment du contexte
; - heap_start = (BX!=0 ? BX : 0x0200)
; - heap_end = 0xFFFE (ou plus petit selon usage)
; Puis initialiser le 1er bloc libre:
; [heap_start+0] size = heap_end-heap_start
; [heap_start+2] flags=0
; [heap_start+4] next_free=0
; [heap_start+6] prev_free=0
; footer à (heap_start+size-2)
clc
ret
; -----------------------
; mem_alloc
; CX = bytes demandés
; Sortie: ES=heap_seg, DI=payload, CF=0 si ok sinon CF=1
; -----------------------
mem_alloc:
; need = align2(CX) + HDR_SIZE + FTR_SIZE
; parcourir free list (first-fit)
; split si reste >= MIN_BLK
; marquer alloué, unlink free list
; ES=heap_seg, DI=blk_off + HDR_SIZE
ret
; -----------------------
; mem_free
; Entrée: ES:DI = payload
; Sortie: CF=0 ok sinon CF=1
; -----------------------
mem_free:
; blk_off = DI - HDR_SIZE
; vérifier, marquer libre
; coalescer prev/next via footer/header
; relinker dans free list
ret
; -----------------------
; mem_dump_reset / mem_dump_next
; -----------------------
mem_dump_reset:
mov ax, [heap_start]
mov [dump_cursor], ax
clc
ret
mem_dump_next:
; si dump_cursor >= heap_end => CF=1
; lire size/flags à dump_cursor
; renvoyer AL état, CX taille payload, DI=offset header, ES=heap_seg
; dump_cursor += size
ret