org 0x0000 ; Adresse de début bootloader

	jmp 0x07C0:debut ; On est chargé dans le segment 0x07C0
debut:
	; Met les segments utiles au segment de code courant
	mov ax, cs
	mov ds, ax
	call detect_cpu

initialise_disque: ; Initialise le lecteur de disque
	xor ax, ax
	int 0x13
	jc initialise_disque; En cas d'erreur on recommence (sinon, de toute façon, on ne peut rien faire)

lire:
	mov ax, 0x1000 ; ES:BX = 1000:0000
	xor bx, bx
	mov es, ax
	mov ah, 2 ; Fonction 0x02 : chargement mémoire
	mov al, 6 ; On s'arrête au secteur n° 6
	xor ch, ch ; Premier cylindre (n° 0)
	mov cl, 2 ; Premier secteur (porte le n° 2, le n° 1, on est dedans, et le n° 0 n'existe pas)
	; Ca fait donc 5 secteurs
	xor dh, dh ; Tête de lecture n° 0
	; Toujours pas d'identifiant de disque, c'est toujours le même.
	int 0x13 ; Lit !
	jc lire ; En cas d'erreur, on recommence
	mov si, sautNoyau ; Un petit message pour rassurer les troupes.
	call affiche_chaine
	jmp 0x1000:0000 ; Et on donne la main au programme que nous venons de charger

detect_cpu:
	mov si, processormsg ; Dit à l' utilisateur ce qu'on est en train de faire
	call affiche_chaine

	mov si, proc8086 ; De base, on considère qu'il s'agit d'un 8086
	pushf ; sauvegarde les valeurs originales des drapeaux

	; teste si un 8088/8086 est présent (les bits 12-15 sont à 1)
	xor ah, ah ; Met les bits 12-15 à 0
	call test_drapeaux
	cmp ah, 0xF0
	je finDetectCpu ; 8088/8086 détecté

	mov si, proc286 ; On considère qu'il s'agit d'un 286
	; teste si un 286 est présent (les bits 12-15 sont effacés)
	mov ah, 0xF0 ; Met les bits 12-15 à 1
	call test_drapeaux
	jz finDetectCpu ; 286 détecté

	mov si, proc386 ; aucun 8088/8086 ou 286, donc c' est un 386 ou plus
finDetectCpu:
	popf ; restaure les valeurs originales des flags	
	call affiche_chaine
	ret

test_drapeaux:
	push ax ; copie AX dans la pile
	popf ; Récupère AX en tant que registre de drapeaux. Les bits 12-15 sont initialisés pour le test
	pushf ; Remet le registre de drapeaux sur la pile
	pop ax ; Les drapeaux sont mis dans AX pour analyse
	and ah, 0xF0 ; Ne garde que les bits 12-15
	ret

affiche_chaine:
	push ax
	push bx
	push cx
	push dx
	xor bh, bh; RAZ de bh, qui stocke la page d'affichage
	mov ah, 0x03
	int 0x10; appel de l'interruption BIOS qui donne la position du curseur, stockée dans dx
	mov cx, 1; nombre de fois où l'on va afficher un caractère
affiche_suivant:
	lodsb
	or al, al;on compare al à zéro pour s'arrêter
	jz fin_affiche_suivant
	cmp al, 13
	je nouvelle_ligne
	mov ah, 0x0A;on affiche le caractère courant cx fois
	int 0x10
	inc dl; on passe à la colonne suivante pour la position du curseur
	cmp dl, 80
	jne positionne_curseur
nouvelle_ligne:
	inc dh; on passe à la ligne suivante
	xor dl, dl; colonne 0
positionne_curseur:
	mov ah, 0x02;on positionne le curseur
	int 0x10
	jmp affiche_suivant
fin_affiche_suivant:
	pop dx
	pop cx
	pop bx
	pop ax
	ret
;fin de affiche_chaine

proc8086: db '8086', 13, 0
proc286: db '286', 13, 0
proc386: db '386', 13, 0
processormsg: db 'Test du processeur : ', 0
sautNoyau: db 'Saut au noyau', 13, 0
times 510-($-$$) db 0
dw 0xAA55
