; LIBI16.TXT

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

; La bibliotheque offre les sous-programmes mathematiques pour les nombres
;   fixes codes sur 16 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 6 registres directs :
;   direct  RE10, xxh   ; LSB du premier operande ou premier resultat
;   direct  RE11, xxh   ; MSB du premier operande ou premier resultat
;   direct  RE20, xxh   ; LSB du second operande ou second resultat
;   direct  RE21, xxh   ; MSB du second operande ou second resultat
;   direct  TMP0, xxh   ; LSB du resultat intermediaire
;   direct  TMP1, xxh   ; MSB du resultat intermediaire

; Le chargement ou sauvegarde des resultats ou des operandes s'effectue
;   par chargement  :
;       dans la memoire externe   (ex : I16ReadExtREx),
;       dans la memoire programme (ex : I16ReadProgREx),
;       dans la memoire interne   (ex : I16ReadIntREx).
; L'octet de poid faible est stocke en tete (avec l'adresse la plus basse).

; Les operations s'effectuent en signe (ex I16Mul) ou en non signe
;   (ex I16UMul).

; 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 :
;   I16ReadExtRE1               Lecture de RE1 depuis la memoire externe
;   I16ReadExtRE2               Lecture de RE2 depuis la memoire externe
;   I16ReadProgRE1              Lecture de RE1 depuis la memoire programme
;   I16ReadProgRE2              Lecture de RE2 depuis la memoire programme
;   I16ReadIntRE1               Lecture de RE1 depuis la memoire interne
;   I16ReadIntRE2               Lecture de RE2 depuis la memoire interne
;   I16WriteExtRE1              Ecriture de RE1 dans la memoire externe
;   I16WriteExtRE2              Ecriture de RE2 dans la memoire externe
;   I16WriteIntRE1              Ecriture de RE1 dans la memoire interne
;   I16WriteIntRE2              Ecriture de RE2 dans la memoire interne
;   I16ClearRE1                 Mise a 0 de RE1
;   I16UAdd                     RE1=RE1+RE2 (non signe)
;   I16USub                     RE1=RE1-RE2 (non signe)
;   I16UMul                     RE1=RE1*RE2 (non signe)
;   I16UDiv                     RE1=RE1/RE2 et RE2=RE1%RE2 (non signe)
;   I16ShLeRE1                  RE1=RE1<<A (decalage a gauche non signe)
;   I16ShLeRE2                  RE2=RE2<<A (decalage a gauche non signe)
;   I16ShRiRE1                  RE1=RE1>>A (decalage a droite non signe)
;   I16ShRiRE2                  RE2=RE2>>A (decalage a droite non signe)
;   I16NegRE1                   RE1=-RE1
;   I16SgnRE1                   C=Signe de RE1
;   I16AbsRE1                   RE1=Valeur absolue de RE1
;   I16Add                      RE1=RE1+RE2 (signe)
;   I16Sub                      RE1=RE1-RE2 (signe)
;   I16Mul                      RE1=RE1*RE2 (signe)
;   I16Div                      RE1=RE1/RE2 et RE2=RE1%RE2 (signe)
;   I16Cvti16toi08RE1           RE1 converti de 16 a 8 bits en signe
;   I16Cvti08toi16RE1           RE1 converti de 8 a 16 bits en signe
;   I16UCvti16toi08RE1          RE1 converti de 16 a 8 bits en non signe
;   I16UCvti08toi16RE1          RE1 converti de 8 a 16 bits en non signe

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

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

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

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

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

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

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

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

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

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

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

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

I16USub:
    Fonction  :   Soustraction non signee de deux nombres de 16 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    :   ?

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

I16UDiv:
    Fonction  :   Division non signee de deux nombres de 16 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=ffffh), C=0 sinon
    Utilise   :   Registres TMP1, TMP0, A, PSW et B non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I16ShLeRE1:
    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    :   ?

I16ShLeRE2:
    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    :   ?

I16ShRiRE1:
    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    :   ?

I16ShRiRE2:
    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    :   ?

I16NegRE1:
    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=8000h=-32768) et C=0 sinon
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   2 avec l'appel
    Cycles    :   ?

I16SgnRE1:
    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    :   ?

I16AbsRE1:
    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=8000h=-32768)
                  C=0 si nombre compatible d'un codage signe
    Utilise   :   Registres A et PSW non sauvegardes
    Pile      :   4 avec l'appel
    Cycles    :   ?

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

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

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

I16Div:
    Fonction  :   Division signee de deux nombres de 16 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=7fffh ou 8000h
                                    selon le signe de RE1)
                                  - debordement du quotien en signe (+32768)
                  C=0 si pas d'erreur
    Utilise   :   Registres TMP1, TMP0, A, PSW et B non sauvegardes
    Pile      :   4 avec l'appel
    Cycles    :   ?

I16Cvti16toi08RE1:
    Fonction  :   Conversion signee de 16 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    :   ?

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

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

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