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 ‡ 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 ‡ 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 ‡ 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 ‡ 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 ‡ 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 ‡ 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 ‡ 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‡ 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‡ 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 ‡ 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.