Obligement - L'Amiga au maximum

Vendredi 29 mars 2024 - 12:07  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in english


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Blitz Basic - calculette rudimentaire (2e partie)
(Article écrit par Sylvain Terret - avril 2005)


Une calculette un peu moins rudimentaire

Le programme de ce mois-ci est une évolution de celui du mois dernier. Nous obtenons cette fois une calculette capable d'additionner, soustraire, multiplier ou diviser deux entiers positifs compris entre 0 et 99. Et, fin du fin, elle sait gérer correctement les résultats de soustraction négatifs. La classe.

Je vous propose sans plus attendre de lire le listing et de consulter les explications que j'y ai adjointes pour bien comprendre ce qu'il se passe.

====== DEBUT SOURCE

WBStartup
WbToScreen 3
Use Screen 3

LoadFont 2,"topaz.font",8
Use IntuiFont 2

;On déclare nos variables...
;...codées sur un mot en prévision d'évolutions futures (word ; 16 bits)
chiffre_un.w=0
chiffre_deux.w=0
;...codées sur 32 bits (long)
resultat.l=0

;Voici (re)venir la GadgetList numéro 0
;On prépare les boutons +, -, * et /
GTButton 0,1,10,0,40,15,"+",$10
GTButton 0,2,10,20,40,15,"-",$10
GTButton 0,3,10,40,40,15,"*",$10
GTButton 0,4,10,60,40,15,"/",$10

;On prépare les deux zones de saisie qui acceptent désormais 2 chiffres
GTString 0,5,80,20,40,15,"",$10,2
GTString 0,6,80,40,40,15,"",$10,2

;On ouvre le fenêtre numéro 0 et on en fait la sortie par défaut
Window 0,0,14,320,120,$140e,"Un peu d'ASM 68k avec le Blitz",-1,-1
DefaultOutput

;On attache la GadgetList numéro 0 à la fenêtre numéro 0
AttachGTList 0,0

Use Window 0


;Boucle principale du programme
While ev.l<>$200

 ;On récupère les événements qui se produisent dans la fenêtre du logiciel
 ev.l=Event

 WindowOutput 0

 ;Si on clique sur un bouton
 ;et que l'on a bien saisi deux chiffres
 If (GTGetString(0,5)<>"") AND (GTGetString(0,6)<>"")
 AND (Len(GTGetString(0,5))<3) AND (Len(GTGetString(0,6))<3)
  If ev.l=64
   ;Si on clique sur le bouton +
   If GadgetHit=1
    ;Nos zones de saisie contenant de la chaîne de caractères
    ;on doit les transformer en chiffres avec la fonction VAL()
    chiffre_un.w=Val(GTGetString(0,5))
    chiffre_deux.w=Val(GTGetString(0,6))
    ;On met tout le registre processeur D0 à 0
    CLR.l d0
    ;On met le contenu de la variable entière codée sur
    ;un word nommé CHIFFRE_UN dans le registre de données D0 du 68000 
    GetReg d0,chiffre_un.w
    ;Même traitement pour D1, il ne faut pas qu'il reste de cochonneries dedans
    CLR.l d1
    GetReg d1,chiffre_deux.w
    ;On ajoute les 16 bits de poids faible de la valeur contenue dans le registre
    ;D0 à celle contenue dans D1 et on stocke le résultat dans D1
    ADD.w d0,d1
    ;On transfère le contenu de D1 dans la variable entière codée sur 32 bits
    ;nommée RESULTAT
    PutReg d1,resultat.l
    ;On positionne le curseur de texte dans la fenêtre
    WLocate 10,100
    Print Str$(chiffre_un.w)+" + "+Str$(chiffre_deux.w)+" = "+Str$(resultat.l)+"      "
   EndIf
   ;Si on clique sur le bouton -
   If GadgetHit=2
    chiffre_un.w=Val(GTGetString(0,5))
    chiffre_deux.w=Val(GTGetString(0,6))
    CLR.l d0
    GetReg d0,chiffre_un.w
    CLR.l d1
    GetReg d1,chiffre_deux.w
    SUB.w d1,d0
    ;C'est à partir d'ici que les choses changent
    ;On teste l'état du bit numéro 15 (le 16e bit donc ; ils sont numérotés de
    ;droite (0) à gauche (15)) du registre de données D0 du 68000
    BTST #15,d0
    ;Si le 16e bit (aussi appelé "bit de poids fort", car c'est lui qui a la plus
    ;forte influence sur la valeur décimale codée) est égal à zéro
    ;cela signifie que le nombre placé dans D0 est positif (les nombres négatifs
    :sont codifiés en utilisant la méthode du complément à deux ; voir le cours
    ;de Krabob à ce sujet)
    ;sachez juste que je procède de cette manière, car en complément à deux, les
    ;nombres négatifs commencent toujours par un 1.
    ;L'instruction 68000 BNE signifie Branch if Not Equal. Ici, on saute au label
    ;NEGATIF si le résultat de BTST est différent de 0 (donc 1)
    BNE NEGATIF:
    ;L'instruction 68000 BEQ signifie Branch if Equal. Ici, on saute au label
    ;POSITIF si le résultat de BTST est 0
    BEQ POSITIF:
    NEGATIF:
    ;Si on a affaire à un nombre négatif, on inverse la procédure de codage en
    ;complément à deux
    ;On inverse donc les 16 premiers bits du registre D0 (les bits de poids faible,
    ;ceux qui sont le plus à droite)
    NOT.w d0
    ;On ajoute 1 à D0 pour achever la manipulation
    ;On se retrouve donc avec le chiffre réel en positif
    ADD.w #1,d0
    PutReg d0,resultat.l
    WLocate 10,100
    Print Str$(chiffre_un.w)+" - "+Str$(chiffre_deux.w)+" = -"+Str$(resultat.l)+"      "
    ;Si mes souvenirs sont bons, l'instruction BRA n'est pas à proprement parler une
    ;instruction native 68000, il s'agit plus d'une macro
    ;BRA = Branch Anyway
    ;Donc quoi qu'il arrive, on saute au label FIN
    BRA FIN:
    POSITIF:
    PutReg d0,resultat.l
    WLocate 10,100
    Print Str$(chiffre_un.w)+" - "+Str$(chiffre_deux.w)+" = "+Str$(resultat.l)+"      "
    FIN:
   EndIf
   ;Si on clique sur le bouton *
   If GadgetHit=3
    chiffre_un.w=Val(GTGetString(0,5))
    chiffre_deux.w=Val(GTGetString(0,6))
    CLR.l d0
    GetReg d0,chiffre_un.w
    CLR.l d1
    GetReg d1,chiffre_deux.w
    MULU.w d0,d1
    PutReg d1,resultat.l
    WLocate 10,100
    Print Str$(chiffre_un.w)+" * "+Str$(chiffre_deux.w)+" = "+Str$(resultat.l)+"      "
   EndIf
   ;Si on clique sur le bouton /
   If GadgetHit=4
    chiffre_un.w=Val(GTGetString(0,5))
    chiffre_deux.w=Val(GTGetString(0,6))
    CLR.l d0
    GetReg d0,chiffre_un.w
    CLR.l d1
    GetReg d1,chiffre_deux.w
    DIVU.l d1,d0
    PutReg d0,resultat.l
    WLocate 10,100
    Print Str$(chiffre_un.w)+" / "+Str$(chiffre_deux.w)+" = "+Str$(resultat.l)+"      "
   EndIf
  EndIf
 EndIf

Wend

DetachGTList 0
Free Window 0

End

====== FIN SOURCE

Bien que le source soit déjà pas mal commenté, je vais détailler la méthode utilisée pour détecter les résultats de soustraction négatifs :

1/ SUB.w d1,d0 -> je soustrais D1 à D0 et stocke le résultat dans D0.
2/ BTST #15,d0 -> on teste l'état de l'octet numéro 15 du registre D0 dans lequel a été enregistré le résultat de la soustraction.
3/ BNE NEGATIF: -> si le 16e octet (souvenez-vous qu'ils sont numérotés de 0 à 15) est égal à 1, alors le résultat est négatif.
4/ BEQ POSITIF: -> si le 16e octet est égal à 0, alors le résultat est positif.

Voici le traitement du résultat négatif :

NEGATIF:
     NOT.w d0
     ADD.w #1,d0
     PutReg d0,resultat.l
     WLocate 10,100
     Print Str$(chiffre_un.w)+" - "+Str$(chiffre_deux.w)+" = -"+Str$(resultat.l)+"      "
     BRA FIN:

Vous vous demandez peut-être pourquoi je fais tout ce tintouin, alors j'explique : les nombres négatifs sont codifiés en utilisant la méthode dite du "complément à deux", ce qui fait que D0 ne contient pas un résultat directement utilisable comme cela est le cas pour un nombre positif. Il faut d'abord le décoder afin d'obtenir quelque chose de cohérent pour l'utilisateur de la calculatrice. Par exemple, sans traitement, le résultat de l'opération 5-10 donnerait 65 531 (65 536-5), ce n'est pas franchement ce qu'on attend comme résultat, non ? Alors il faut le mouliner.

En faisant un NOT sur un WORD, j'inverse les 16 octets de poids faible de D0. Admettons que D0 contienne 1001000011001100, il deviendra 1001000000110011. Après, on lui ajoute 1 pour achever le décodage du complément à deux et on obtient un chiffre positif correspondant au résultat humainement logique de notre soustraction.

J'aimerais revenir sur la question du poids des octets. Tout tient dans la manière dont on numérise les chiffres. En base 2, sur 8 bits, 5 se code comme suit : 0000 0101. L'octet le plus à droite vaut 1, son voisin, 2, puis 4, 8, 16, 32, 64 et enfin 128 pour celui qui est le plus à gauche. Il apparaît clairement qu'une modification de cet octet aura une plus grande incidence sur le résultat qu'une altération de l'octet de droite : ajouter 128 à un nombre provoque un changement plus conséquent que si on lui ajoute seulement 1. C'est de là que viennent les expresions "octet de poids le plus fort/faible".

Voilà pour cette fois. Vous vous rendez sans doute compte que, bien que le listing n'a pas beaucoup changé, il y a quand même des notions importantes qui montrent le bout de leur nez. L'assembleur ou l'art de transformer un pet de mouche en explosion nucléaire. Bon, Ok, j'abuse.


[Retour en haut] / [Retour aux articles] [Article précédent]