; LIBI32.TXT

;       Bibliotheque mathematique pour les entiers sur 32 bits
;       ------------------------------------------------------
;
;                     (C) E+E CHAMOUARD 2001

; La bibliotheque offre les sous-programmes mathematiques pour les nombres
;   fixes codes sur 32 bits en complement a deux pour les nombres signes
;   et en binaire pur pour les nombres non signes.

; Elle utilise les memes conventions que les autres bibliotheques mathematiques
;   (code de retour en cas d'erreur,...) et (obligatoirement) les memes registres.

; La bibliotheque travaille sur 3 groupes de registres :
;   RE1x pour le premier operande ou premier resultat,
;   RE2x pour le second operande ou second resultat,
;   TMPx pour le registre temporaire.

; Le programme principal doit donc definir 12 registres directs :
;   direct  RE10, xxh   ; LSB du premier operande ou premier resultat
;   direct  RE11, xxh   ;
;   direct  RE12, xxh   ;
;   direct  RE13, xxh   ; MSB du premier operande ou premier resultat
;   direct  RE20, xxh   ; LSB du second operande ou second resultat
;   direct  RE21, xxh   ;
;   direct  RE22, xxh   ;
;   direct  RE23, xxh   ; MSB du second operande ou second resultat
;   direct  TMP0, xxh   ; LSB du resultat intermediaire
;   direct  TMP1, xxh   ;
;   direct  TMP2, xxh   ;
;   direct  TMP3, xxh   ; MSB du resultat intermediaire

; Le chargement ou sauvegarde des resultats ou des operandes s'effectue
;   par chargement  :
;       dans la memoire externe   (ex : I32ReadExtREx),
;       dans la memoire programme (ex : I32ReadProgREx),
;       dans la memoire interne   (ex : I32ReadIntREx).
; Les octets de poid faible sont stockes en tete (avec l'adresse la plus basse).

; Les operations s'effectuent en signe (ex I32Mul) ou en non signe
;   (ex I32UMul).

; La carry (C) est positionnee en cas de debordement ou d'erreur (division)
;   pour tous les sous-programmes sauf ceux de chargement ou de sauvegarde.

; Liste des sous-programmes :
;   I32ReadExtRE1               Lecture de RE1 depuis la memoire externe
;   I32ReadExtRE2               Lecture de RE2 depuis la memoire externe
;   I32ReadProgRE1              Lecture de RE1 depuis la memoire programme
;   I32ReadProgRE2              Lecture de RE2 depuis la memoire programme
;   I32ReadIntRE1               Lecture de RE1 depuis la memoire interne
;   I32ReadIntRE2               Lecture de RE2 depuis la memoire interne
;   I32WriteExtRE1              Ecriture de RE1 dans la memoire externe
;   I32WriteExtRE2              Ecriture de RE2 dans la memoire externe
;   I32WriteIntRE1              Ecriture de RE1 dans la memoire interne
;   I32WriteIntRE2              Ecriture de RE2 dans la memoire interne
;   I32ClearRE1                 Mise a 0 de RE1
;   I32UAdd                     RE1=RE1+RE2 (non signe)
;   I32USub                     RE1=RE1-RE2 (non signe)
;   I32UMul                     RE1=RE1*RE2 (non signe)
;   I32UDiv                     RE1=RE1/RE2 et RE2=RE1%RE2 (non signe)
;   I32ShLeRE1                  RE1=RE1<<A (decalage a gauche non signe)
;   I32ShLeRE2                  RE2=RE2<<A (decalage a gauche non signe)
;   I32ShRiRE1                  RE1=RE1>>A (decalage a droite non signe)
;   I32ShRiRE2                  RE2=RE2>>A (decalage a droite non signe)
;   I32NegRE1                   RE1=-RE1
;   I32NegRE2                   RE2=-RE2
;   I32SgnRE1                   C=Signe de RE1
;   I32AbsRE1                   RE1=Valeur absolue de RE1
;   I32Add                      RE1=RE1+RE2 (signe)
;   I32Sub                      RE1=RE1-RE2 (signe)
;   I32Mul                      RE1=RE1*RE2 (signe)
;   I32Div                      RE1=RE1/RE2 et RE2=RE1%RE2 (signe)
;   I32Cvti32toi08RE1           RE1 converti de 32 a 8 bits en signe
;   I32Cvti08toi32RE1           RE1 converti de 8 a 32 bits en signe
;   I32Cvti32toi16RE1           RE1 converti de 32 a 16 bits en signe
;   I32Cvti16toi32RE1           RE1 converti de 16 a 32 bits en signe
;   I32UCvti32toi08RE1          RE1 converti de 32 a 8 bits en non signe
;   I32UCvti08toi32RE1          RE1 converti de 8 a 32 bits en non signe
;   I32UCvti32toi16RE1          RE1 converti de 32 a 16 bits en non signe
;   I32UCvti16toi32RE1          RE1 converti de 16 a 32 bits en non signe

I32ReadExtRE1:
    Fonction  :   Lecture de 32 bits de la memoire externe vers l'operande/resultat RE1
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   RE1={@DPTR+3,@DPTR+2,@DPTR+1,@DPTR} (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ReadExtRE2:
    Fonction  :   Lecture de 32 bits de la memoire externe vers l'operande/resultat RE2
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   RE2={@DPTR+3,@DPTR+2,@DPTR+1,@DPTR} (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ReadProgRE1:
    Fonction  :   Lecture de 32 bits de la memoire programme vers l'operande/resultat RE1
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   RE1={@DPTR+3,@DPTR+2,@DPTR+1,@DPTR} (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ReadProgRE2:
    Fonction  :   Lecture de 32 bits de la memoire programme vers l'operande/resultat RE2
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   RE2={@DPTR+3,@DPTR+2,@DPTR+1,@DPTR} (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ReadIntRE1:
    Fonction  :   Lecture de 32 bits de la memoire interne vers l'operande/resultat RE1
    Entree(s) :   Dans R0 l'adresse de la donnee
    Sortie(s) :   RE1={@R0+3,@R0+2,@R0+1,@R0} (R0 incremente de 4 cases)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ReadIntRE2:
    Fonction  :   Lecture de 32 bits de la memoire interne vers l'operande/resultat RE2
    Entree(s) :   Dans R0 l'adresse de la donnee
    Sortie(s) :   RE2={@R0+3,@R0+2,@R0+1,@R0} (R0 incremente de 4 cases)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32WriteExtRE1:
    Fonction  :   Ecriture de 32 bits de l'operande/resultat RE1 vers la memoire externe
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   {@DPTR+3,@DPTR+2,@DPTR+1,@DPTR}=RE1 (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32WriteExtRE2:
    Fonction  :   Ecriture de 32 bits de l'operande/resultat RE2 vers la memoire externe
    Entree(s) :   Dans {DPH,DPL} l'adresse de la donnee
    Sortie(s) :   {@DPTR+3,@DPTR+2,@DPTR+1,@DPTR}=RE2 (DPTR incremente de 4 cases)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32WriteIntRE1:
    Fonction  :   Ecriture de 32 bits de l'operande/resultat RE1 vers la memoire interne
    Entree(s) :   Dans R0 l'adresse de la donnee
    Sortie(s) :   {@R0+3,@R0+2,@R0+1,@R0}=RE1 (R0 incremente de 4 cases)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32WriteIntRE2:
    Fonction  :   Ecriture de 32 bits de l'operande/resultat RE2 vers la memoire interne
    Entree(s) :   Dans R0 l'adresse de la donnee
    Sortie(s) :   {@R0+3,@R0+2,@R0+1,@R0}=RE2 (R0 incremente de 4 cases)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ClearRE1:
    Fonction  :   RAZ de l'operande/resultat RE1
    Entree(s) :   Rien
    Sortie(s) :   RE1={0,0,0,0} (C=0)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UAdd:
    Fonction  :   Addition non signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1+RE2 (RE2 inchange)
                  C=1 si debordement (RE1+RE2>ffffffffh), C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32USub:
    Fonction  :   Soustraction non signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1-RE2 (RE2 inchange)
                  C=1 si debordement (RE1<RE2), C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UMul:
    Fonction  :   Multiplication non signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1*RE2 (RE2 inchange)
                  C=1 si debordement (RE1*RE2>ffffffffh), C=0 sinon
    Utilise   :   Registres TMP3 a TMP0, A, PSW et B non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UDiv:
    Fonction  :   Division non signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 (numerateur) et RE2 (denominateur)
    Sortie(s) :   RE1=RE1/RE2 et RE2=RE1%RE2
                  C=1 si erreur (denominateur=0 et dans ce cas RE1=ffffffffh), C=0 sinon
    Utilise   :   Registres TMP3 a TMP0, A, PSW et B non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ShLeRE1:
    Fonction  :   Decalage a gauche de l'operande/resultat RE1
    Entree(s) :   Donnee dans RE1, nombre de decalages dans A
    Sortie(s) :   RE1=RE1<<A (decalage a gauche non signe)
                  Avec C=0 meme si debordement, A perdu
    Utilise   :   Registres A,B et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ShLeRE2:
    Fonction  :   Decalage a gauche de l'operande/resultat RE2
    Entree(s) :   Donnee dans RE2, nombre de decalages dans A
    Sortie(s) :   RE2=RE2<<A (decalage a gauche non signe)
                  Avec C=0 meme si debordement, A perdu
    Utilise   :   Registres A,B et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ShRiRE1:
    Fonction  :   Decalage a droite de l'operande/resultat RE1
    Entree(s) :   Donnee dans RE1, nombre de decalages dans A
    Sortie(s) :   RE1=RE1>>A (decalage a gauche non signe)
                  Avec C=0 meme si debordement, A perdu
    Utilise   :   Registres A,B et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32ShRiRE2:
    Fonction  :   Decalage a droite de l'operande/resultat RE2
    Entree(s) :   Donnee dans RE2, nombre de decalages dans A
    Sortie(s) :   RE2=RE2>>A (decalage a gauche non signe)
                  Avec C=0 meme si debordement, A perdu
    Utilise   :   Registres A,B et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32NegRE1:
    Fonction  :   Changement de signe de l'operande/resultat RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   RE1=-RE1
                  Avec C=1 si debordement (si RE1=80000000h=-2147483648) et C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32NegRE2:
    Fonction  :   Changement de signe de l'operande/resultat RE2
    Entree(s) :   Donnee dans RE2
    Sortie(s) :   RE2=-RE2
                  Avec C=1 si debordement (si RE2=80000000h=-2147483648) et C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32SgnRE1:
    Fonction  :   Recuperation du signe de l'operande/resultat RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   C=0 si le nombre est positif ou nul
                  C=1 si le nombre est negatif
                  RE1 reste inchange
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32AbsRE1:
    Fonction  :   Valeur absolue de l'operande/resultat RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   RE1=ABS(RE1)
                  C=1 si debordement en codage signe (RE1=80000000=-2147483648)
                  C=0 si nombre compatible d'un codage signe
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   4 avec l'appel
    Cycles    :   ?

I32Add:
    Fonction  :   Addition signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1+RE2 (RE2 inchange)
                  C=1 si debordement (RE1+RE2>7fffffffh ou <80000000h), C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32Sub:
    Fonction  :   Soustraction signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1-RE2 (RE2 inchange)
                  C=1 si debordement (RE1-RE2>7fffffffh ou <80000000h), C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32Mul:
    Fonction  :   Multiplication signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 et RE2
    Sortie(s) :   RE1=RE1*RE2 (RE2=abs(RE2))
                  C=1 si debordement (RE1*RE2>7fffffffh ou <80000000h), C=0 sinon
    Utilise   :   Registres TMP3, TMP2, TMP1, TMP0, A, PSW et B non sauvegardes
    Pile      :   4 avec l'appel
    Cycles    :   ?

I32Div:
    Fonction  :   Division signee de deux nombres de 32 bits
    Entree(s) :   Donnees dans RE1 (numerateur) et RE2 (denominateur)
    Sortie(s) :   RE1=RE1/RE2 et RE2=RE1%RE2
                  C=1 si erreur : - denominateur=0 et dans ce cas RE1=7fffffffh ou 80000000h
                                    selon le signe de RE1)
                                  - debordement du quotien en signe (+214748348)
                  C=0 si pas d'erreur
    Utilise   :   Registres TMP3, TMP2, TMP1, TMP0, A, PSW et B non sauvegardes
    Pile      :   4 avec l'appel
    Cycles    :   ?

I32Cvti32toi08RE1:
    Fonction  :   Conversion signee de 32 bits vers 8 bits dans RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   Donnee convertie sur 8 bits dans RE10
                  Avec C=1 si RE1>127 ou RE1<-128, C=0 sinon
                  Dans tous les cas RE10=RE1[256] et RE11=0 si >0 RE11=ffh sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32Cvti08toi32RE1:
    Fonction  :   Conversion signee de 8 bits vers 32 bits dans RE1
    Entree(s) :   Donnee dans RE10
    Sortie(s) :   Donnee convertie sur 32 bits dans RE1 (C=0)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32Cvti32toi16RE1:
    Fonction  :   Conversion signee de 32 bits vers 16 bits dans RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   Donnee convertie sur 16 bits dans {RE11,RE10}
                  Avec C=1 si RE1>32767 ou RE1<-32768, C=0 sinon
                  Dans tous les cas {RE11,RE10}=RE1[65536] et RE13=RE12=0 si >=0 RE13=RE12=ffh sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32Cvti16toi32RE1:
    Fonction  :   Conversion signee de 16 bits vers 32 bits dans RE1
    Entree(s) :   Donnee dans {RE11,RE10}
    Sortie(s) :   Donnee convertie sur 32 bits dans RE1 (C=0)
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UCvti32toi08RE1:
    Fonction  :   Conversion non signee de 32 bits vers 8 bits dans RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   Donnee convertie sur 8 bits dans RE10
                  Avec C=1 si debordement (RE1>255), C=0 sinon
                  Dans tous les cas RE10=RE1[256] et {RE13,RE12,RE11}={0,0,0}
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UCvti08toi32RE1:
    Fonction  :   Conversion non signee de 8 bits vers 32 bits dans RE1
    Entree(s) :   Donnee dans RE10
    Sortie(s) :   Donnee convertie sur 32 bits dans RE1 (C=0)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UCvti32toi16RE1:
    Fonction  :   Conversion non signee de 32 bits vers 16 bits dans RE1
    Entree(s) :   Donnee dans RE1
    Sortie(s) :   Donnee convertie sur 16 bits dans {RE11,RE10}
                  Avec C=1 si debordement (RE1>65535), C=0 sinon
                  Dans tous les cas {RE11,RE10}=RE1[65536] et {RE13,RE12}={0,0}
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I32UCvti16toi32RE1:
    Fonction  :   Conversion non signee de 16 bits vers 32 bits dans RE1
    Entree(s) :   Donnee dans {RE11,RE10}
    Sortie(s) :   Donnee convertie sur 32 bits dans RE1 (C=0)
    Utilise   :   Rien
    Pile      :   2 avec l'appel
    Cycles    :   ?
