Programme.asm

Contenu du snippet

programme.asm est en quelque sorte un noyau simple en asm permettant un affichage en mode texte des entrées du clavier.

Source / Exemple :


org 0x0000 ; Adresse de dÈbut .COM

jmp start
%include "affichageTexte.asm"

start:
;On initialise Data Segment et Extra Segment ‡ Code Segment
	call initialise_segments

	mov si, hello; met l'adresse de la chaÓne ‡ afficher dans le registre SI
	call affiche_chaine
ecran:
	mov ax, 0x4F00 ; demande infos sur le pilote VESA VBE
	mov di, VESASignature
	int 10h
	cmp ax, 0x4F ; Si AL <> 0x4F, on n'a pas de VESA, donc fin. Si AH <> O, erreur, donc fin.
	jne fin
	mov si, OEMStringPtr ; pointeur vers le nom de l'OEM stockÈ offset:segment
	lodsw; on charge l'adresse d'offset dans ax
	mov bx, ax ; BX contient l'adresse d'offset
	lodsw ; on charge l'adresse de segment dans ax
	mov si, bx ; SI pointe sur le nom de l'OEM
	push ds ; on sauvegarde DS
		mov ds, ax ; ds contient l'adresse de segment du nom de l'OEM
		call affiche_chaine
	pop ds ; on restaure DS

	mov cx , 18
lignes_vides:
	mov si, retour_chariot
	call affiche_chaine
	loop lignes_vides

	mov si, VideoModePtr ; pointeur vers la liste des modes supportÈs
	lodsw ; on charge l'adresse d'offset dans ax
	mov cx, ax ; cx contient l'adresse d'offset
	lodsw ; on charge l'adresse de segment dans ax
	mov si, cx ; si pointe sur le premier mode supportÈ
	mov dx, ax ; dx contient l'adresse de segment
lit_mode_suivant:
	push ds
		mov ds, dx ; ds contient l'adresse de segment de la liste des modes
		lodsw ;charge dans ax le mode
	pop ds
	cmp ax, 0xFFFF ; Fin de la liste
	je arret_modes
	mov cx, ax
	mov ax, 0x4F01 ; demande infos sur le mode VESA
	mov di, ModeAttributes
	int 0x10
	cmp ax, 0x4F ; Si AL <> 0x4F, la fonction n'est pas supportÈe, on se contentera du VGA. Si AH <> O, erreur, pareil.
	jne lit_mode_suivant
	test word [ModeAttributes], 0xF
	jz lit_mode_suivant
;On ecrit les modes
	mov di, hello ; on Ècrit dans hello
	mov ax, cx
	push cx
		mov ch, 3
		mov bl, 16
		call nombre_vers_chaine
		mov al, ':'
		stosb
		mov ch, 4
		mov bl, 10
		mov ax, [XResolution]
		call nombre_vers_chaine
		mov ax, ('*' << 8) + ' '
		stosw
		mov al, ' '
		stosb
		mov ax, [YResolution]
		call nombre_vers_chaine
		mov ax, ' '
		stosb
		mov ch, 2
		mov al, [BitsPerPixel]
		call nombre_vers_chaine
		mov al, ' '
		stosb
		mov ax, ';' ; on met 2 caractËres d'un coup aprËs la chaÓne : un '\n' et le zÈro terminal.
		stosw ; les caractËres sont dÈpilÈs, c'est &#8225; dire qu'il faut placer le premier dans la zone basse
	pop cx
    push si ;sauve si sur la pile
		mov si, hello
		call affiche_chaine
    pop si ; on rÈcupËre si
	push dx
		mov ax, [XResolution]
		shr ax, 5
		push ax
			mov ax, [YResolution]
			shr ax, 3
			push ax
				mov al, [BitsPerPixel]
				xor ah, ah
				shr ax, 3
			pop bx
			mul bx
		pop bx
		mul bx
	pop dx
	cmp ax, [maxResol]
	jb lit_mode_suivant
	mov [maxResol], ax
	mov [mode_souhaite], cx
    jmp lit_mode_suivant
arret_modes:
	mov cx, [mode_souhaite] ; On s'enquiert du mode souhaitÈ
    mov ax, 0x4F01 ; demande infos sur le mode VESA
	mov di, ModeAttributes
    int 0x10
	mov di, hello ; on Ècrit dans hello
	mov ax, cx
	push cx
		mov ch, 3
		mov bl, 16
		call nombre_vers_chaine
		mov al, ':'
		stosb
		mov ch, 4
		mov bl, 10
		mov ax, [XResolution]
		call nombre_vers_chaine
		mov ax, ('*' << 8) + ' '
		stosw
		mov al, ' '
		stosb
		mov ax, [YResolution]
		call nombre_vers_chaine
		mov ax, ' '
		stosb
		mov ch, 2
		mov al, [BitsPerPixel]
		call nombre_vers_chaine
		mov ax, 13 ; on met 2 caractËres d'un coup aprËs la chaÓne : un '\n' et le zÈro terminal.
		stosw ; les caractËres sont dÈpilÈs, c'est &#8225; dire qu'il faut placer le premier dans la zone basse
	pop cx
    mov si, hello
    call affiche_chaine

    mov ax, [WinASegment]
    or ax, ax ; on teste l'adresse du segment de la fenÍtre. Si elle est nulle, on passe en mode 0x13
    jnz adresse_OK
adresse_mode_13h:
    mov word [mode_souhaite], 0x0013 ; infos du mode 0x13, le mode VGA
    mov word [WinASegment], 0xA000
    mov word [YResolution], 200
    mov word [XResolution], 320
;    mov word [largeur_memoire], 320
adresse_OK:
	mov di, hello ; met l'adresse de la chaÓne &#8225; lire dans le registre SI
	call lit_chaine ; On attend l'utilisateur pour nettoyer l'Ècran

	mov ax, 0x4F02
	mov bx, [mode_souhaite]
	int 0x10 ; Changement de mode vidÈo
	call nettoyage_ecran
	mov ax, 10 ; CoordonnÈe Y
	mov bx, 10 ; CoordonnÈe X
	;	mov dx, 0x04; Couleur
	call affiche_point	
	mov bx, 160 ; CoordonnÈe X
	mov ax, 100 ; CoordonnÈe Y
;	mov dx, 0x04; Couleur
	call affiche_point
	mov bx, 319 ; CoordonnÈe X
	mov ax, 199 ; CoordonnÈe Y
;	mov dx, 0x03; Couleur
	call affiche_point
	mov bx, 639 ; CoordonnÈe X
	mov ax, 399 ; CoordonnÈe Y
;	mov dx, 0x03; Couleur
	call affiche_point
	mov bx, 639 ; CoordonnÈe X
	mov ax, 479 ; CoordonnÈe Y
;	mov dx, 0x03; Couleur
	call affiche_point
	mov bx, 799 ; CoordonnÈe X
	mov ax, 599 ; CoordonnÈe Y
;	mov dx, 0x03; Couleur
	call affiche_point
	mov bx, 1279 ; CoordonnÈe X
	mov ax, 1023 ; CoordonnÈe Y
;	mov dx, 0x03; Couleur
	call affiche_point
	jmp fin
	push 100
	push 10
	push 100
	push 20
	mov dx, 0x03; Couleur
	call affiche_ligne
	add sp, 8
	push 102
	push 20
	push 102
	push 10
	mov dx, 0x05; Couleur
	call affiche_ligne
	add sp, 8
	push 114
	push 10
	push 104
    push 10
    mov dx, 0x06; Couleur
    call affiche_ligne
    add sp, 8
    push 104
    push 20
    push 114
    push 20
    mov dx, 0x07; Couleur
    call affiche_ligne
    add sp, 8
    push 126
    push 20
    push 124
    push 10
    mov dx, 0x08; Couleur
    call affiche_ligne
    add sp, 4
    push 116
    push 18
    mov dx, 0x09; Couleur
    call affiche_ligne
    add sp, 4
    push 124
    push 30
    mov dx, 0x0A; Couleur
    call affiche_ligne
    add sp, 4
    push 116
    push 22
    mov dx, 0x0B; Couleur
    call affiche_ligne
    add sp, 4
    push 132
    push 10
    mov dx, 0x0C; Couleur
    call affiche_ligne
    add sp, 4
    push 136
    push 16
    mov dx, 0x0D; Couleur
    call affiche_ligne
    add sp, 4
    push 136
    push 24
    mov dx, 0x0E; Couleur
    call affiche_ligne
    add sp, 4
    push 132
    push 30
    mov dx, 0x0F; Couleur
    call affiche_ligne
    add sp, 8
    push 10
    push 10
    push 310
    push 190
    mov dx, 0x02; Couleur
    call affiche_ligne
    add sp, 8
;    push 511
;    push 614
;    push 1000
;    push 614
;    mov dx, 0x03; Couleur
;    call affiche_ligne
;    add sp, 8
;    mov di, hello; met l'adresse de la chaÓne &#8225; lire dans le registre SI
;    call lit_chaine ; On attend la volontÈ de l'utilisateur
;    mov ax, 0x4F02 ; Retour au mode texte
;    mov bx, 0x0003; 80 * 25, mode texte
;    int 0x10

initialise_disque: ; Initialise un disque
    mov ax, 0
    mov dl, 0           ; Lecteur = 0 (= A)
    int 0x13
    jc initialise_disque ; En cas d'erreur, on recommence

lire_disque:
    mov ax, 0x2000      ; ES:BX = 2000:0000
    mov es, ax
    xor bx, bx
    mov ah, 2           ; charge les donnÈes en ES:BX
    mov al, 6           ; charge jusqu'au secteur 6
    xor ch, ch          ; premier cylindre
    mov cl, 1           ; premier secteur
    xor dh, dh          ; premiËre tÍte de lecture
    int 0x13            ; Lit
    jc lire_disque      ; En cas d'erreur, on recommence

initialise_HD: ; Initialise le disque dur
    mov ax, 0
    mov dl, 0x80 ; Lecteur = 0x80 (=C)
    int 0x13
    jc initialise_HD         ; En cas d'erreur, on recommence

ecrit_disque:
    mov ax, 0x2000      ; ES:BX = 2000:0000
    mov es, ax
    xor bx, bx
    mov ah, 3           ; Ecrit &#8225; partir de ES:BX
    mov al, 6           ; Ecrit jusqu'au secteur 6
    xor ch, ch          ; premier cylindre
    mov cl, 1           ; premier secteur
    xor dh, dh          ; premiËre tÍte de lecture
    int 0x13            ; Ecrit
    jc ecrit_disque     ; En cas d'erreur, on recommence

fin:
    jmp $
;    ret

lit_chaine:
    push ax
    push cx
    push dx
    mov ah, 0x03
    int 0x10; appel de l'interruption BIOS qui donne la position du curseur, stockÈe dans dx
    mov cx, 1
attend_clavier:
    mov ah, 0x01;on teste le buffer clavier
    int 0x16
    jz attend_clavier
    ;al contient le code ASCII du caractËre
    xor ah, ah; on lit le buffer clavier
    int 0x16
    stosb
    cmp al, 13
    je fin_attend_clavier
    ;al contient le code ASCII du caractËre
    mov ah, 0x0A;on affiche le caractËre courant cx fois
    int 0x10
    inc dl; on passe &#8225; la colonne suivante pour la position du curseur
    mov ah, 0x02;on positionne le curseur
    int 0x10
    jmp attend_clavier
fin_attend_clavier:
    inc dh; on passe &#8225; la ligne suivante pour la position du curseur
    xor dl, dl
    mov ah, 0x02;on positionne le curseur
    int 0x10
    mov byte [di], 0;on met le caractËre terminal dans si
    pop dx
    pop cx
    pop ax
    ret
;fin de lit_chaine

;fonction affiche_point : on est dÈj&#8225; dans un mode graphique
;BX : CoordonnÈe X du point
;AX : CoordonnÈe Y du point
;dL : Couleur du point
affiche_point:
    push bx ; On sauve les registres qu'on va manipuler
		push cx
			push es
				push di
					push dx
						push ax
							mov cx, word [BytesPerScanLine]
							mul	cx
							mov di, ax
							push dx
								mov ax, bx
								xor ch, ch
								mov cl, [BitsPerPixel]
								shr cx, 3
								mul cx
								add di, ax
							pop dx
						.change_fenetre:
							mov ax, 0x4F05
							xor bh, bh
							xor bl, bl
							int 0x10 ; Changement de fenÍtre
						bloc_OK:
							mov es, [WinASegment] ; On va dans la mÈmoire vidÈo
							mov ax, 0xFFFF ; On fixe la couleur du pixel
							stosw ; Et on l'Ècrit dans la mÈmoire vidÈo
							stosw
						pop ax ; On restaure les registres manipulÈs
					pop dx
				pop di
			pop es
		pop cx
	pop bx
	ret
;fin de affiche_point

;fonction affiche_ligne : on est dÈj&#8225; dans un mode graphique
; DL contient la couleur
affiche_ligne:
    jmp depart_affiche_ligne
Y2: dw 0
X2: dw 0
Y1: dw 0
X1: dw 0
deltaX: dw 0
deltaY: dw 0
incX: dw 0
incY: dw 0
e: dw 0
couleur: db 0
depart_affiche_ligne:
    push si
    push ax
    push bx
    push cx
    push dx
    push di
    push es
    mov ax, sp
    mov si, ax
    add si, 16 ; SI pointe sur Y2
    mov di, Y2
    mov ax, ds
    mov es, ax
    mov ax, ss
    mov ds, ax
    mov cx, 4
    rep movsw
    mov ax, es
    mov ds, ax
    mov [couleur], dl
    mov ax, [X2]
    mov bx, [X1]
    sub ax, bx
    mov [deltaX], ax
    mov cx, [Y2]
    mov bx, [Y1]
    sub cx, bx
    mov [deltaY], cx
    or ax, ax ; test deltaX
    jnz test_deltaX_positif
    or cx, cx ; test deltaY
    jnz test_deltaY_deltaX_nul
fin_affiche_ligne:
    mov dl, [couleur]
    mov ax, [X2]
    mov bx, [Y2]
    call affiche_point
    mov ax, [X1]
    mov bx, [Y1]
    call affiche_point
    pop es
    pop di
    pop dx
    pop cx
    pop bx
    pop ax
    pop si
    ret

deltaX_positif:
    or cx, cx
    jnz test_deltaY_deltaX_positif
    ;vecteur horizontal vers la droite
    mov cx, [deltaX]
    mov dx, 1
    mov word [incX], 1
    mov word [incY], 0
    jmp ligne_H_V

test_deltaY_deltaX_nul:
    mov word [incY], 1
    mov word [incX], 0
    cmp cx, 0
    jns ligne_H_V
    neg cx
    mov word [incY], -1
ligne_H_V:
    mov ax, [X1]
    mov bx, [Y1]
    mov dl, [couleur]
boucle_H_V:
    loop avance_H_V
    jmp fin_affiche_ligne

avance_H_V:
    add ax, [incX]
    add bx, [incY]
    call affiche_point
    jmp boucle_H_V

test_deltaX_positif:
    cmp ax, 0
    jns deltaX_positif
    or cx, cx
    jnz test_deltaY_deltaX_negatif
    ;vecteur horizontal vers la gauche
    mov cx, [deltaX]
    neg cx
    mov dx, -1
    mov word [incX], -1
    mov word [incY], 0
    jmp ligne_H_V

charge_registres:
    shl cx, 1
    shl ax, 1
    mov [deltaY], cx
    mov [deltaX], ax
    mov ax, [X1]
    mov bx, [Y1]
    ret

charge_e_deltaX_et_cmp_X2:
    mov [e], ax
    call charge_registres
    mov cx, [X2]
    ret

charge_e_deltaY_et_cmp_Y2:
    mov [e], cx
    call charge_registres
    mov cx, [Y2]
    ret

affiche_et_charge_eY:
    mov dl, [couleur]
    call affiche_point
    add bx, [incY]
    mov dx, [e]
    ret

affiche_et_charge_eX:
    mov dl, [couleur]
    call affiche_point
    add ax, [incX]
    mov dx, [e]
    ret

octants1_et_4:
    call charge_e_deltaX_et_cmp_X2
depart_boucle1:
    call affiche_et_charge_eX
    cmp ax, cx
    je fin_affiche_ligne
    sub dx, [deltaY]
    cmp dx, 0
    jns X_pret1
    add bx, [incY]
    add dx, [deltaX]
X_pret1:
    mov [e], dx
    jmp depart_boucle1

deltaY_positif_deltaX_negatif:
    neg ax
deltaY_positif_deltaX_positif:
    mov word [incY], 1
    ;deltaY > 0, deltaX > 0
    cmp ax, cx
    jae octants1_et_4
    neg ax
    call charge_e_deltaY_et_cmp_Y2
depart_boucle2_et_3:
    call affiche_et_charge_eY
    cmp bx, cx
    je fin_affiche_ligne
    add dx, [deltaX]
    cmp dx, 0
    jns X_pret2_et_3
    add ax, [incX]
    add dx, [deltaY]
X_pret2_et_3:
    mov [e], dx
    jmp depart_boucle2_et_3

octant5:
    call charge_e_deltaX_et_cmp_X2
depart_boucle5:
    call affiche_et_charge_eX
    cmp ax, cx
    je fin_affiche_ligne
    sub dx, [deltaY]
    cmp dx, 0
    js X_pret5
    add bx, [incY]
    add dx, [deltaX]
X_pret5:
    mov [e], dx
    jmp depart_boucle5

octant8:
    neg cx
    call charge_e_deltaX_et_cmp_X2
depart_boucle8:
    call affiche_et_charge_eX
    cmp ax, cx
    je fin_affiche_ligne
    add dx, [deltaY]
    cmp dx, 0
    jns X_pret8
    add bx, [incY]
    add dx, [deltaX]
X_pret8:
    mov [e], dx
    jmp depart_boucle8

test_deltaY_deltaX_positif:
    mov word [incX], 1
    cmp cx, 0
    jns deltaY_positif_deltaX_positif
    ;deltaY < 0, deltaX > 0
    mov word [incY], -1
    neg cx
    cmp ax, cx
    jae octant8
    neg cx
    jmp octants6_et_7

test_deltaY_deltaX_negatif:
    mov word [incX], -1
    cmp cx, 0
    jns deltaY_positif_deltaX_negatif
    ;deltaY < 0, deltaX < 0
    mov word [incY], -1
    cmp ax, cx
    jbe octant5
    neg ax
octants6_et_7:
    call charge_e_deltaY_et_cmp_Y2
depart_boucle6_et_7:
    call affiche_et_charge_eY
    cmp bx, cx
    je fin_affiche_ligne
    add dx, [deltaX]
    cmp dx, 0
    js X_pret6_et_7
    add ax, [incX]
    add dx, [deltaY]
X_pret6_et_7:
    mov [e], dx
    jmp depart_boucle6_et_7
;AFFICHE_LIGNE ENDP

nettoyage_ecran:
    push di
    push es
    push ax
    push bx
    push cx
    push dx
    mov es, [WinASegment]; On lit l'adresse de dÈpart de la mÈmoire vidÈo

    mov cx, [YResolution]
    mov ax, [XResolution]
    mul cx	; Nombre de points total
    mov ax, dx
	mov cl, [BitsPerPixel]
	shr cl, 3
	mul	cl
	mov cx, ax
    xor dx, dx
    xor bh, bh
	xor bl, bl
boucle_fenetres:
    push cx
		mov ax, 0x4F05
		int 0x10 ; Changement de fenÍtre
		mov cx, 0x8000 ; Nombre de mots dans un morceau d'Ècran
		xor di, di
	.point:	
		mov ax, [couleur_defaut]
		stosw
		mov ax, [couleur_defaut+2]
		stosw
		loop .point
		inc dx
    pop cx
    loop boucle_fenetres
.depile:
    xor dx, dx
    mov [bloc_courant], dl
    mov ax, 0x4F05
    int 0x10 ; Changement de fenÍtre
    pop dx
    pop cx
    pop bx
    pop ax
    pop es
    pop di
    ret
;Fin nettoyage_ecran

;Initialisation des segments
initialise_segments:
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ax, 0x8000
    cli
    mov ss, ax
    mov sp, 0xF000
    sti
	ret
;Fin initialisation segments

mode_souhaite: dw 0x0013
maxResol: dw 0
couleur_defaut: db 0x0F, 0x0F, 0x0F, 0xFF; B, G, R, A
largeur_memoire: dw 320
bloc_courant: db 0
disquettes: db ' lecteur(s) de disquette installÈ(s).', 13, 0
pas: db 'Pas de ', 0
coprocesseur: db 'Coprocesseur arithmÈtique.', 13, 0
memoire_dispo: db ' ko.', 13, 0
au_demarrage: db ' au dÈmarrage.', 13, 0
DMA: db 'DMA.', 13, 0
RS232: db ' port(s) RS232 disponible(s).', 13, 0
manette: db 'Manette de jeu.', 13, 0
modem_interne: db 'Modem interne.', 13, 0
imprimantes: db ' imprimante(s) connectÈe(s).', 13, 0
heure: db '00 h 00 min 00 s', 13, 0
retour_chariot: db 13, 0
nombre_de_cylindres: db ' cylindres.', 13, 0
nombre_de_tetes: db ' tetes.', 13, 0
nombre_de_secteurs: db ' secteurs par piste.', 13, 0
pas_33h: db 'Pas d`interruption 0x33.', 13, 0
;Informations du pilote VESA
VESASignature: times 4 db 0; /* 'VESA' 4 byte signature */
VESAVersion: dw 0; /* VBE version number */
OEMStringPtr: dd 0; /* Pointer to OEM string */
Capabilities: dd 0; /* Capabilities of video card */
VideoModePtr: dd 0; /* Pointer to supported modes */
TotalMemory: dw 0; /* Number of 64kb memory blocks */
reserved: times 236 db 0; /* Pad to 256 byte block size */
;Informations d'un mode vidÈo
ModeAttributes: dw 0; /* Mode attributes */
WinAAttributes: db 0; /* Window A attributes */
WinBAttributes: db 0; /* Window B attributes */
WinGranularity: dw 0; /* Window granularity in k */
WinSize: dw 0; /* Window size in k */
WinASegment: dw 0; /* Window A segment */
WinBSegment: dw 0; /* Window B segment */
WinFuncPtr: dd 0; /* Pointer to window function */
BytesPerScanLine: dw 0; /* Bytes per scanline */
XResolution: dw 0; /* Horizontal resolution */
YResolution: dw 0; /* Vertical resolution */
XCharSize: db 0; /* Character cell width */
YCharSize: db 0; /* Character cell height */
NumberOfPlanes: db 0; /* Number of memory planes */
BitsPerPixel: db 0; /* Bits per pixel */
NumberOfBanks: db 0; /* Number of CGA style banks */
MemoryModel: db 0; /* Memory model type */
BankSize: db 0; /* Size of CGA style banks */
NumberOfImagePages: db 0; /* Number of images pages */
res1: db 0; /* Reserved */
RedMaskSize: db 0; /* Size of direct color red mask */
RedFieldPosition: db 0; /* Bit posn of lsb of red mask */
GreenMaskSize: db 0; /* Size of direct color green mask */
GreenFieldPosition: db 0; /* Bit posn of lsb of green mask */
BlueMaskSize: db 0; /* Size of direct color blue mask */
BlueFieldPosition: db 0; /* Bit posn of lsb of blue mask */
RsvdMaskSize: db 0; /* Size of direct color res mask */
RsvdFieldPosition: db 0; /* Bit posn of lsb of res mask */
DirectColorModeInfo: db 0; /* Direct color mode attributes */
res2: times 216 db 0; /* Pad to 256 byte block size */
hello: db 'Bonjour papi. Je cherche une ligne de plus de quatre vingts caractËres. Ce doit Ítre relativement facile &#8225; trouver, non ?', 13, 0
times 4096-($-$$) db 0

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Du même auteur (aminadaou)