BITS 	32
org 	0x06000

%define RAM_VIDEO 	0xb8000
%define MBR_ADRESSE (0x07c0<<4)

;On va copier les infos VESA du chargeur d'amorçage dans nos données
	mov esi, 512 + MBR_ADRESSE
	mov edi, VESASignature
	mov ecx, 512/4
	rep movsd

	mov esi, 1024 + MBR_ADRESSE
	mov edi, NbEntreesMemoire
	movsw
	xor ecx, ecx
	mov cx, word[NbEntreesMemoire]
	mov eax, ecx
	shl ecx, 1
	add ecx, eax
	shl ecx, 1
	rep movsd

	call init_pic

	mov cx, 8*3		;En route pour le 3ème segment
	mov es, cx
	call nettoyageEcran

	mov dword [couleurPoint], 0xFFFFFFFF
	mov eax, 0x00100000
	mov ebx, 0x001A0000
    call afficheLigne
	mov eax, 0x000C0000
	mov ebx, 0x000C000A
	call afficheLigne
	mov eax, 0x000E000A
	mov ebx, 0x000E0000
	call afficheLigne
	mov eax, 0x001A000A
	mov ebx, 0x0010000A
	call afficheLigne
	mov eax, 0x01000100
	mov ebx, 0x01800130
	call afficheLigne
	mov ebx, 0x018000D0
	call afficheLigne
	mov ebx, 0x01300180
	call afficheLigne
	mov ebx, 0x01300080
	call afficheLigne
	mov ebx, 0x00800130
	call afficheLigne
	mov ebx, 0x008000D0
	call afficheLigne
	mov ebx, 0x00D00180
	call afficheLigne
	mov ebx, 0x00D00080
	call afficheLigne

	mov cx, 8*2		;En route pour le 2e segment
	mov es, cx
	mov dword [curseur], 0
	mov esi, chaine
	call afficheChaine
	
	;Affichage de la carte mémoire
	mov edi, chaine
	xor eax, eax
	mov ax, word [NbEntreesMemoire]
	mov ebx, 10
	mov cl, 1
	mov ch, 8
	call nombreVersChaine
	mov esi, chaine
	call afficheChaine
	mov esi, DonneesMemoire
	mov edi, 0;memoireUtilisee
	mov dword [curseur], 16
	mov cx, word [NbEntreesMemoire]
	mov ebx, 16
s5:
	push ecx
	mov ecx, 6		;Une entrée mémoire : 6 double-mots
s1:
	push ecx
	lodsd
	push eax
	push esi
	push edi
	mov edi, chaine
	mov cl, 1
	mov ch, 8
	call nombreVersChaine
	mov esi, chaine
	call afficheChaine
	pop edi
	pop esi
	pop eax
	pop ecx
	cmp ecx, 2 ; le double-mot qui dit si on peut utiliser cette plage
	je memoireUtile
s2:
	loop s1

	add word [curseur], 7
	mov word [curseur+2], 0
	pop ecx
	loop s5

	mov eax, -1;Marque de fin de l'espace allouable : fin des racines
	stosd
	add dword[prochainPointeur], 4
	
;	mov cx, 3;word [NbEntreesMemoire]
;	mov esi, 0
;	mov ebx, 16
;a1:
;	push ecx
;	mov ecx, 5		;Une entrée mémoire : 5 doule-mots
;a2:
;	push ecx
;	lodsd
;	push esi
;	push edi
;	mov edi, chaine
;	mov cl, 1
;	mov ch, 8
;	call nombreVersChaine
;	mov esi, chaine
;	call afficheChaine
;	pop edi
;	pop esi
;	pop ecx
;a3:
;	loop a2

;	add word [curseur], 7
;	mov word [curseur+2], 0
;	pop ecx
;	loop a1

;	mov ecx, 110
;	add word [curseur], 8
;	mov word [curseur+2], 0
;	xor eax, eax
;afficheAlphabet:
;	call afficheCaractere
;	inc al
;	loop afficheAlphabet

;	add word [curseur], 8
;	mov word [curseur+2], 0
	mov bx, 8*2		;En route pour le 2ème segment
	mov es, bx
	mov ecx, 0x001000 ;Taille maximum de l'arbre
;	shr ecx, 1
	call malloc

	xor ecx, ecx
	mov edi, chaine
	mov cl, 1
	mov ch, 8
	call nombreVersChaine

	mov esi, chaine
	call afficheChaine
	add word [curseur], 7
	mov word [curseur+2], 0
	
	mov ecx, 10*4;10 chaînes max
	call malloc
	mov [texteEditeur], eax;Adresse du tableau des pointeurs
	mov [pointeurTexte], eax;Adresse du premier pointeur

	xor ecx, ecx
	mov edi, chaine
	mov cl, 1
	mov ch, 8
	call nombreVersChaine

	mov esi, chaine
	call afficheChaine
	add word [curseur], 7
	mov word [curseur+2], 0
princ:
	mov ecx, 0x00800 ;Taille maximum d'une ligne : 2048 caractères
	call malloc
	push eax
	mov edi, [pointeurTexte]
	stosd

	xor ecx, ecx
	mov edi, chaine
	mov cl, 1
	mov ch, 8
	call nombreVersChaine

	mov esi, chaine
	call afficheChaine

	pop eax
	mov edi, eax
	mov esi, edi
	call litChaine
	lodsb
	cmp al, 48
	je fin
	
	add dword[pointeurTexte], 4
	jmp princ;$
fin:
	mov cx, 8*3		;En route pour le 3e segment
	mov es, cx
	call nettoyageEcran
	mov dword [curseur], 0

	mov cx, 8*2		;En route pour le 2e segment
	mov es, cx
	mov eax, dword[texteEditeur]
	mov dword[pointeurTexte], eax

	mov ecx, 10
.boucle:
	mov esi, [pointeurTexte]
	lodsd
	mov esi, eax
	call afficheChaine
	add dword [pointeurTexte], 4
	loop .boucle
	jmp $

texteEditeur: dd 0
pointeurTexte: dd 0

memoireUtile:
	cmp eax, 1
	je .ajoute
	cmp eax, 3
	jne .retour
.ajoute:
	sub esi, 20
	movsd	;On stocke l'adresse de la zone mémoire
	add esi, 4
	movsd	;On stocke la taille disponible
	xor eax, eax;	On met la taille utilisée à 0
	stosd
	mov eax, -1
	stosd
	stosd
	add esi, 8
	add dword[prochainPointeur], 5*4
.retour:
	jmp s2

afficheArbre:
	push eax
	push ebx
	push ecx
	push esi
	push edi
	mov ebx, 16
	mov ecx, 5		;Une entrée mémoire : 5 double-mots
.a2:
	push ecx
	lodsd
	push esi
	push edi
	mov edi, chaine
	mov cl, 1
	mov ch, 8
	call nombreVersChaine
	mov esi, chaine
	call afficheChaine
	pop edi
	pop esi
	pop ecx
.a3:
	loop .a2
	add word [curseur], 7
	mov word [curseur+2], 0
	pop edi
	pop esi
	pop ecx
	pop ebx
	pop eax
	ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; malloc															;;
;;------------------------------------------------------------------;;
;; Réserve une certaine quantité de mémoire.						;;
;; ECX contient la taille à réserver								;;
;; EAX contient l'adresse de la mémoire réservée					;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
malloc:
	;ECX contient la taille à réserver
	push esi
	push ebx
	mov ebx, 0
.suivant:
	mov esi, ebx
	lodsd
	cmp eax, -1
	je .fin
	push esi

	mov esi, ebx;memoireUtilisee	;Initialisation de la lecture des données mémoire
	call .parcours

	pop esi
	cmp eax, -1
	jne .fin
	add ebx, 4*5
	jmp .suivant
.fin:
	pop ebx
	pop esi
	ret

.parcours:
	call afficheArbre
	push ebx
	push esi
	push edx
	push edi
	lodsd						;Lecture de la zone allouée
	mov ebx, eax				;La première adresse disponible est celle que l'on vient de lire
	lodsd						;On lit la taille du bloc
	mov edx, eax
	lodsd						;On lit la taille de la mémoire réservée
	add eax, ecx
	cmp eax, edx
	ja .retourInvalide			;On sort si on n'a pas la place dans ce bloc
	mov eax, edx
	shr eax, 1					;On va diviser par 2
	cmp ecx, eax				;On compare par rapport à la taille souhaitée
	ja	.prendTout				;Si la taille souhaitée est plus grande que la moitié de la taille dispo, on va prendre tout.
;Sinon, a priori, on va prendre un fils
	mov edi, esi				;Mise à jour de l'espace d'écriture
	lodsd						;On lit l'adresse du fils gauche
	cmp eax, 0xFFFFFFFF			;Si l'adresse est 0xFFFFFFFF, il s'agit du pointeur invalide.
	je .fixePointeur
;Sinon, on regarde ce qu'il a dans le ventre
	push esi
	mov esi, eax
	call .parcours
	pop esi
	sub esi, 16
	cmp eax, 0xFFFFFFFF			;Si l'adresse n'est pas 0xFFFFFFFF, il s'agit d'un pointeur valide.
	jne .ajoutTailleFils

	add esi, 16

	mov edi, esi				;Mise à jour de l'espace d'écriture
	lodsd						;On lit l'adresse du fils droit
	cmp eax, 0xFFFFFFFF			;Si l'adresse est 0xFFFFFFFF, il s'agit du pointeur invalide.
	je .fixePointeurDroit
;Sinon, on regarde ce qu'il a dans le ventre
	push esi
	mov esi, eax
	call .parcours
	pop esi
	sub esi, 20
	cmp eax, 0xFFFFFFFF			;Si l'adresse n'est pas 0xFFFFFFFF, il s'agit d'un pointeur valide.
	jne .ajoutTailleFils
.retourInvalide:
	mov eax, -1
	jmp .retour

.ajoutTailleFils:
	add esi, 8
	mov edi, esi
	push eax
	lodsd
	add eax, ecx
	stosd
	pop eax
	jmp .retour

.prendTout:
;Avant de prendre tout, on va faire quelques petites vérifs.
	sub esi, 4
	mov edi, esi		;Mise à jour de l'espace d'écriture
	lodsd
	and eax, eax		;Y a-t-il eu une réservation sur le bloc ?
	jnz .retourInvalide	;Oui : on passe au bloc suivant
;Pas de réservation sur le bloc.
	mov eax, edx
	mov ecx, edx
	stosd
	mov eax, ebx
.retour:
	pop edi
	pop edx
	pop esi
	pop ebx
	ret

.fixePointeur:
	sub esi, 16
	push esi
	mov eax, edx				;Sa taille est la moitié de celle de son père.
	shr eax, 1
	push eax	;Stocke la taille
	push ebx	;Stocke l'adresse de départ
	jmp .completeFils

.fixePointeurDroit:
	sub esi, 20
	push esi
	mov eax, edx				;La taille de son frère gauche est la moitié de celle de son père.
	shr eax, 1
	sub edx, eax
	add eax, ebx				;Son adresse de départ est celle de son père + la taille de son frère.
	push edx	;Stocke la taille
	push eax	;Stocke l'adresse de départ

.completeFils:
	mov eax, [prochainPointeur]	;Où doit être le fils
	stosd						;On remplace le pointeur invalide par la bonne adresse
	mov esi, eax
	mov edi, eax				;On va écrire dans ce fils

	pop eax
	stosd
	pop eax
	stosd
	xor eax, eax
	stosd						;Pour l'instant, on n'en utilise rien
	mov eax, -1					;Ses enfants sont invalides
	stosd
	stosd

	mov eax, [prochainPointeur]	;Où doit être le fils
	mov esi, eax
	add dword[prochainPointeur], 5 * 4;Pour le prochain
	call .parcours			;On va voir si par hasard, on ne serait pas sur la bonne valeur
	pop esi
	jmp .ajoutTailleFils
prochainPointeur: dd 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fin malloc														;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

%include "interruptions.asm"
%include "video.asm"
%include "chaines.asm"
%include "alphabet.asm"

chaine:
	db 	93,78,11,19,51,19,13,19,51,31,24,15,51,29,31,26,15,28,12,15,51,16,25,24,13,30,19,25,24,51,14,78,11,16,16,19,13,18,11,17,15,51,14,15,51,30,15,34,30,15,51,27,31,19
	db  51,24,15,51,29,11,31,28,11,19,30,51,26,22,11,24,30,15,28,51,29,31,28,51,31,24,51,23,11,22,18,15,31,28,15,31,34,51,29,11,31,30,51,112,14,15,51,22,19,17,24,15,112,0
	;"J'ai ici une superbe fonction d'affichage de texte qui ne saurait planter sur un malheureux saut ", 13, "de ligne", 13, 0

couleurDefaut: db 0x00, 0x1F, 0x2F, 0x2F; ARBG
couleurPoint: db 0x00, 0x00, 0x7F, 0x00; BGRA
curseur: dw 0
;Informations du pilote VESA
VESASignature: times 4 db 0; 'VESA', signature de 4 octets
VESAVersion: dw 0; numéro de version de VBE
OEMStringPtr: dd 0; Pointeur vers le nom de l'OEM
Capabilities: dd 0; Possibilités de la carte graphique
VideoModePtr: dd 0; Pointeur vers les modes accessibles
TotalMemory: dw 0; Nombre de blocs mémoire de 64ko
reserved: times 236 db 0; Complément à 256 octets, taille du bloc
;Informations d'un mode vidéo
ModeAttributes: dw 0; Attributs du mode
WinAAttributes: db 0; Attibuts de la fenêtre A
WinBAttributes: db 0; Attibuts de la fenêtre B
WinGranularity: dw 0; Granularité de la fenêtre en ko
WinSize: dw 0; Taille de la fenêtre en ko
WinASegment: dw 0; Segment de la fenêtre A
WinBSegment: dw 0; Segment de la fenêtre B
WinFuncPtr: dd 0; Pointeur vers la fonction "de fenêtrage"
BytesPerScanLine: dw 0; Octets par "scanline"
XResolution: dw 0; Résolution horizontale
YResolution: dw 0; Résolution vertical
XCharSize: db 0; Largeur d'un caractère
YCharSize: db 0; Hauteur d'un caractère
NumberOfPlanes: db 0; Nombre de plans mémoire
BitsPerPixel: db 0; Bits par pixel
NumberOfBanks: db 0; Nombre de banques de style CGA
MemoryModel: db 0; Type de modèle mémoire
BankSize: db 0; Taille des banques de style CGA
NumberOfImagePages: db 0; Nombre de pages image
res1: db 0; Reservé
RedMaskSize: db 0; Taille du masque rouge en couleur directe
RedFieldPosition: db 0; Position du bit faible du masque rouge
GreenMaskSize: db 0; Taille du masque vert en couleur directe
GreenFieldPosition: db 0; Position du bit faible du masque vert
BlueMaskSize: db 0; Taille du masque bleu en couleur directe
BlueFieldPosition: db 0; Position du bit faible du masque bleu
RsvdMaskSize: db 0; Taille du masque réservé en couleur directe
RsvdFieldPosition: db 0;  Position du bit faible du masque réservé
DirectColorModeInfo: db 0; Attributs du mode de couleur directe
FlatMemory: dd 0
res2: times 212 db 0; Complément à 256 octets, taille du bloc
NbEntreesMemoire: dw 0
DonneesMemoire: times 6*6 dd -1
memoireUtilisee: dw 0, 0

times 4*1024-($-$$) db 0
