MANDELI.ASM

EnrANI   PROC NEAR

         Mov    Dx,OffSet Animat
         Mov    Ax,3C00h
         Xor    Cx,Cx
         Int    21h
         Mov    BX,AX                  ; BX Handle

         Mov    Cx,21
         Mov    Dx,OffSet SAF
         Mov    Ax,4000h
         Int    21h

         Push   DS                     ; Svg Pallette
         Mov    Cx,768
         Mov    Dx,PAL
         Mov    DS,SegANI
         Mov    Ax,4000h
         Int    21h
         Pop    DS

         Xor    EAX,EAX
         Mov    Ax,NumImg
         Mov    NbImages,EAX

         Mov    Cx,4
         Mov    Dx,OffSet NbImages
         Mov    Ax,4000h
         Int    21h

         Mov    Cx,4
         Mov    Dx,OffSet TailleAnimation
         Mov    Ax,4000h
         Int    21h

         Mov    Cx,1
         Mov    Dx,OffSet TypeANI
         Mov    Ax,4000h
         Int    21h

         Push   DS                     ; Svg Adresses des Imgs
         Mov    Cx,NumImg
         Shl    Cx,2
         Mov    Dx,TabImg
         Mov    DS,SegANI
         Mov    Ax,4000h
         Int    21h
         Pop    DS

         Rol    EBx,16
         Xor    EDi,EDi                ; Offset Svg dans le Son

         Mov    ECx,TailleAnimation
         Mov    Bx,Cx                  ; Nb Oct
         Shr    ECx,16
         Or     Cx,Cx                  ; Nb Bloc de 64Ko
         Je     SautePasTresLoin
         Jmp    UnPeuPlusLoin
SautePasTresLoin:

         Mov    Si,OffSet XMSBloc
         Mov    Cx,Bx
         Mov    Dword Ptr [SI],ECx
         Mov    Ax,XMSHandle
         Mov    [SI+04h],Ax
         Mov    DWord Ptr [SI+06h],EDi
         Mov    DWord Ptr [SI+0Ah],0
         Mov    Ax,Ecran
         Mov    [SI+0Eh],Ax

         Mov    Ah,0Bh
         Call   CS:XMSAd

         Push   Ds
         Mov    Cx,Bx
         Mov    Dx,Ecran
         Mov    Ds,Dx
         Xor    Dx,Dx
         Mov    Ax,4000h
         Rol    EBx,16
         Int    21h
         Rol    EBx,16
         Pop    Ds

         Jmp    FermetureDuFichier
UnPeuPlusLoin:
         Push   Cx

         Mov    Si,OffSet XMSBloc
         Mov    Dword Ptr [SI],65536
         Mov    Ax,XMSHandle
         Mov    [SI+04h],Ax
         Mov    DWord Ptr [SI+06h],EDi
         Mov    DWord Ptr [SI+0Ah],0
         Mov    Ax,Ecran
         Mov    [SI+0Eh],Ax

         Mov    Ah,0Bh
         Call   CS:XMSAd

         Push   Ds
         Mov    Cx,32768
         Mov    Dx,Ecran
         Mov    Ds,Dx
         Xor    Dx,Dx
         Mov    Ax,4000h
         Rol    EBx,16
         Int    21h
         Mov    Cx,32768
         Mov    Dx,32768
         Mov    Ax,4000h
         Int    21h
         Rol    EBx,16
         Pop    Ds

         Add    EDi,10000h
         Pop    Cx
         Loop   UnPeuPlusLoin
         Or     Bx,Bx
         Je     FermetureDuFichier
         Jmp    SautePasTresLoin

FermetureDuFichier:
         Rol    EBx,16                 ; Handle Du Fichier
         Mov    Ax,3E00h
         Int    21h
         Ret
EnrANI   ENDP

; VAR Compress
ArgAdEntr       EQU DWORD PTR [Bp+10]
ArgSegSrc       EQU  WORD PTR [Bp+12]
ArgOfsSrc       EQU  WORD PTR [Bp+10]
ArgAdSort       EQU DWORD PTR [Bp+ 6]
ArgSegDest      EQU  WORD PTR [Bp+ 8]
ArgOfsDest      EQU  WORD PTR [Bp+ 6]
ArgTI           EQU  WORD PTR [Bp+ 4]
; END Compress

CompressW PROC NEAR                    ; En Word
         Push   Bp
         Mov    Bp,Sp
         Push   DS

         Lds    Si,ArgAdEntr
         Les    Di,ArgAdSort
         Mov    Cx,ArgTI

         Xor    Bx,Bx                  ; Taille Compresser
C1:                                    ; Grande Boucle Perdu
         Mov    Dx,1                   ; (C'Est L'autre (C2:))
         LodsB
         Dec    Cx
         Mov    Ah,Al
C2:      LodsB                         ; AH Byte Initiale
         Cmp    Al,Ah
         Jne    PlusDeByteId
         Inc    Dx
         Loop   C2
PlusDeByteId:
         XChg   Al,Ah                  ; Le Byte Qui Se répète est
         Cmp    Dx,4                   ; dans AL
         Jae    LaCompressionVoLeCoup
         Cmp    Al,0FEh
         Jne    OnNAPasPikerMonCode
         StosB
         Push   Ax
         Mov    Ax,Dx
         StosW
         Pop    Ax
         Add    Bx,3
         Jmp    IlFautQuandMemePenserATesterCx
OnNAPasPikerMonCode:
         Push   Cx
         Mov    Cx,Dx
         Rep StosB
         Pop    Cx
         Add    Bx,Dx                  ; Taille Compressé
         Jmp    IlFautQuandMemePenserATesterCx
LaCompressionVoLeCoup:
         Mov    Es:Byte Ptr [DI],0FEh
         Mov    Es:[DI+1],DX
         Mov    Es:[DI+3],Al
         Add    Di,4
         Add    Bx,4
IlFautQuandMemePenserATesterCx:
         Mov    Dx,1                   ; Nombre De Couleur Lu
         JcxZ   FCompress
         Jmp    C2
FCompress:
         Mov    AX,BX
         Pop    DS
         Pop    Bp
         Ret    10
CompressW ENDP

DeCompressW PROC NEAR
         Push   Bp
         Mov    Bp,Sp

         Lds    Si,ArgAdEntr
         Les    Di,ArgAdSort
         Mov    Cx,ArgTI

D1:
         LodsB
         Dec    Cx
         Cmp    Al,0FEh
         Jne    JeConclueQueCeNEstPasUnCode
         LodsW
         Push   Cx
         Cmp    Ax,4
         Jae    CEstDuCompresser
         Mov    Cx,Ax
         Mov    Al,0FEh
         Rep StosB
         Pop    Cx
         Sub    Cx,2
         Jmp    DeCompressAuSuivant
CEstDuCompresser:
         Mov    Cx,Ax
         LodsB
         Rep StosB
         Pop    Cx
         Sub    Cx,3
         Jmp    DeCompressAuSuivant
JeConclueQueCeNEstPasUnCode:
         Stosb
DeCompressAuSuivant:
         JCxZ   FDeCompress
         Jmp    D1
FDeCompress:
         Pop    Bp
         Ret    10
DeCompressW ENDP

ChgPCX   Proc near     ;(OfsNom,SegVar,OfsVar : Word) : Taille
; Var ChgPCX
ArgNom          Equ     Word Ptr [bp+ 8]
ArgSVar         Equ     Word Ptr [bp+ 6]
ArgOVar         Equ     Word Ptr [bp+ 4]         ; OVar = Nom Ds ChgSpt
; End Var ChgPCX

         Push   Bp
         Mov    Bp,Sp
         Push   Ds

         Mov    Dx,ArgNom
         Mov    Ax,3D42h
         Int    21h
         Mov    BX,AX

         Mov    Ax,ArgSVar
         Mov    Ds,Ax
         Mov    Dx,ArgOVar
         Mov    CX,128
         Mov    Ax,3F00h
         Int    21h

         Mov    Ax,ArgSVar
         Mov    Ds,Ax
         Mov    Dx,ArgOVar
         Mov    CX,0FFFFh
         Mov    Ax,3F00h
         Int    21h

         Pop    Ds

         Mov    Ax,3E00h
         Int    21h

         Mov    Sp,Bp
         Pop    Bp
         Clc
         Ret    06h
ChgPCX   EndP

TransPCX PROC NEAR                     ; Seg de Depart,Seg Arrivé WORDS
ArgPalette      EQU Byte Ptr [Bp+8]    ; 1 Affiche Palette
ArgSegImgDep    EQU Word Ptr [Bp+6]    ; 0 N'Affiche Pas le Palette
ArgSegImgArr    EQU Word Ptr [Bp+4]

         Push   BP
         Mov    Bp,Sp

         Push   DS
         Mov    Ax,ArgSegImgArr
         Mov    Es,AX
         Xor    Di,Di
         Mov    Ds,ArgSegImgDep
         Xor    Si,Si
         Mov    Bx,64000

PcxToB:
         Mov    Ah,1
         Lodsb
         Cmp    Al,0C0h
         Jb     PcxD

         Sub    Al,0C0h
         Mov    Ah,Al
         Lodsb

PcxD:    Stosb
         Dec    Bx
         Dec    Ah
         Jg     PcxD
         Or     Bx,Bx
         Je     PcxFin
         Jmp    PcxToB
PcxFin:
         Cmp    ArgPalette,1
         Jne    PasDePalettePCX

         Mov    Ax,Ds
         Mov    Es,Ax

         Inc    Si
         Mov    Dx,SI
         Mov    DI,SI
         Mov    Cx,768
DivisePar4LesCouleurs:
         Lodsb
         Shr    Al,2
         Stosb
         Loop   DivisePar4LesCouleurs

         Mov    ax,01012h
         Mov    bx,0
         Mov    cx,0100h
         Int    10h

PasDePalettePCX:
         Pop    DS
         Pop    BP
         Ret    6
TransPCX ENDP

SetCna   Proc near
         Mov    Ax,Ecran
         Mov    Es,Ax
         Mov    Dx,0
         Add    Dx,64000

         Mov    ax,01012h
         Mov    bx,0
         Mov    cx,0100h
         Int    10h

         Ret
SetCna   EndP

DELAY    PROC NEAR
ArgTime         Equ     Word Ptr [BP+4]
         Push   Bp
         Mov    Bp,Sp
         Push   Ds
         Mov    Ax,40h
         Mov    Ds,Ax
         Mov    Si,6Ch

         Mov    Cx,ArgTime
YesTimeDelay:
         Mov    EAx,DWord Ptr [SI]
EncoreEncoreDl:
         Cmp    EAx,DWord Ptr [SI]
         Je     EncoreEncoreDl
         Loop   YesTimeDelay

         Pop    Ds
         Pop    Bp
         Ret    02h
DELAY    ENDP

CopyWin  PROC    near

         push    bp
         mov     bp,sp
         sub     sp,8
         Push    Ds

         Mov     Ds,ArgVarW0
         Mov     Es,ArgVarW1

         Mov     Ax,ArgYw0
         Mov     Bx,ArgXw0

         xchg	ah,al	; AX := 256*y
         add	bx,ax	; BX := 256*y + x
         shr	ax,1
         shr	ax,1	; AX := 64*y
         add	bx,ax	; BX := 320*y + x
         xchg   Si,bx

         Mov     Ax,ArgYw1
         Mov     Bx,ArgXw1

         xchg	ah,al	; AX := 256*y
         add	bx,ax	; BX := 256*y + x
         shr	ax,1
         shr	ax,1	; AX := 64*y
         add	bx,ax	; BX := 320*y + x
         xchg   Di,bx

         Mov     Dx,320
         Sub     Dx,ArgTxW

         Mov     Cx,ArgTyW
CopWy:   Push    CX
         Mov     CX,ArgTxW
         Test    CL,1
         Je      WordCopY
         Shr     Cx,1
         Rep     MovsW
         MovsB
         Jmp     ContWy
WordCopY:Shr     Cx,1
         Rep     MovsW
ContWy:  Add     DI,Dx                 ; Saut de Ligne
         Add     SI,Dx
         Pop     CX
         Loop    CopWy

         Pop     ds
         mov     sp,bp
         pop     bp
         Ret     16

CopyWin  ENDP

CopyWin1 PROC    near

         push    bp
         mov     bp,sp
         sub     sp,8
         Push    Ds

         Mov     Ds,ArgVarW0
         Mov     Es,ArgVarW1

         Mov     Ax,ArgYw0
         Mov     Bx,ArgXw0

         xchg	ah,al	; AX := 256*y
         add	bx,ax	; BX := 256*y + x
         shr	ax,1
         shr	ax,1	; AX := 64*y
         add	bx,ax	; BX := 320*y + x
         xchg   Si,bx

         Mov     Ax,ArgYw1
         Mov     Bx,ArgXw1

         xchg	ah,al	; AX := 256*y
         add	bx,ax	; BX := 256*y + x
         shr	ax,1
         shr	ax,1	; AX := 64*y
         add	bx,ax	; BX := 320*y + x
         xchg   Di,bx

         Mov     Dx,320
         Sub     Dx,ArgTxW

         Std
         Mov     Cx,ArgTyW
CopWy1:  Push    CX
         Mov     CX,ArgTxW
         Test    CL,1
         Je      WordCopY1
         Shr     Cx,1
         Rep     MovsW
         MovsB
         Jmp     ContWy1
WordCopY1:
         Shr     Cx,1
         Rep     MovsW
ContWy1: Sub     DI,Dx                 ; Saut de Ligne
         Sub     SI,Dx
         Pop     CX
         Loop    CopWy1
         Cld

         Pop     ds
         Mov     sp,bp
         Pop     bp
         Ret     16

CopyWin1 ENDP

Lib387   PROC NEAR
         FFREE   St(7)
         FFREE   St(6)
         FFREE   St(5)
         FFREE   St(4)
         FFREE   St(3)
         FFREE   St(2)
         FFREE   St(1)
         FFREE   St(0)
         RET
Lib387   ENDP

;-- SETFREE:  Libérer la place mémoire inutilisée -----------------------
;-- Entrée    : ES = adresse du PSP
;-- Sortie    : Aucune
;-- Registres : AX, BX, CL et les FLAGS sont modifiés
;-- Infos     : Comme le segment de pile est toujours le dernier segment
;               dans un fichier EXE, ES:0000 désigne le début et SS:SP la
;               fin du programme dans la mémoire. Cela permet de calculer
;               la longueur du programme.
SETFREE  PROC NEAR
         mov  bx,ss            ;Calculer tout d'abord la différence entre
         mov  ax,es            ;les deux adresses de segment, ce qui donne
         sub  bx,ax            ;le nombre de paragraphes du PSP au début de
                               ;la pile.
         mov  ax,sp            ;Comme le pointeur de pile se trouve à la
                               ;fin du segment de pile, son contenu indique
         mov  cl,4
         shr  ax,cl            ;la longueur de la pile
         add  bx,ax            ;Ajouter à la longueur précédante
         inc  bx               ;Un paragraoh de plus par précaution
         mov  ah,4ah           ;Transmettre la nouvelle taille au DOS
         Int  21h
         ret                   ;Retour au programme d'appel
SETFREE  ENDP

ProcessTest PROC Near

         xor  ax,ax
         push ax
         popf
         pushf
         pop  ax
         and  ax,0f000h
         cmp  ax,0f000h
         je   Pas_386

         mov  ax,07000h
         push ax
         popf
         pushf
         pop  ax
         and  ax,07000h
         je   Pas_386

         FInit
         Fld1
         Fldz
         Fld    St
         Fchs
         FCompp
         FStSw  Copro387
         Mov    Ax,Copro387
         Mov    Copro387,0
         SahF
         Je     PasCopro387
         Mov    Copro387,1
PasCopro387:
         STC
         RET
Pas_386: CLC
         RET
ProcessTest ENDP

XMSTest  PROC NEAR
         Mov    Ax,4300h
         Int    2Fh
         Cmp    Al,80h
         Jne    PasDriverXMS
         Mov    Ax,4310h
         Int    2Fh                    ; Adresse XMM ES:BX
         Mov    XmsOfs,BX
         Mov    XmsSeg,ES

         Mov    Ah,0
         Call   CS:XmsAd
         Cmp    Ax,200h
         Jb     MauvaiseVersionDXMS

         Mov    Ah,8
         Call   CS:XmsAd
         Sub    Ax,64
         Cmp    Dx,AX
         Jb     XmsLibreMem
         Sub    Dx,64
XmsLibreMem:
         Cmp    Dx,XmsMinMem
         Jb     PasAssezDeMemoireXMSLibre

         Mov    XMSTaille,DX

         Mov    Ah,9
         Call   CS:XmsAd
         Or     Ax,Ax
         Je     ErreurDeGestionXMS

         Mov    XmsHandle,DX

         Clc
         Ret
ErreurDeGestionXMS:
         Mov    Ah,3
         Mov    Bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,28
         Mov    Bp,Offset ProbXMS
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h
         Jmp    ErreurDXMS
PasAssezDeMemoireXMSLibre:
         Mov    Ah,3
         Mov    Bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,25
         Mov    Bp,Offset PasAssXMS
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h
         Jmp    ErreurDXMS
MauvaiseVersionDXMS:
         Mov    Ah,3
         Mov    Bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,24
         Mov    Bp,Offset MauvXMS
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h
         Jmp    ErreurDXMS
PasDriverXMS:
         Mov    Ah,3
         Mov    Bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,32
         Mov    Bp,Offset PasXMS
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h
ErreurDXMS:
         Stc
         Ret
XMSTest  ENDP

PROG     PROC FAR

         Mov    ax,data
         Mov    ds,ax
         Call   Setfree

         Mov    Ax,Es
         Mov    PrefixSeg,Ax

         PushA

         Push   ES
         CALL   ProcessTEST
         Jc     BonPrcs
         Jmp    Process
BonPrcs:
         Call   XMSTEST
         Jnc    IlYABienDeLXMS
         Jmp    PrgF
IlYABienDeLXMS:

         Mov    Ah,30h
         Int    21h
         Cmp    Al,5
         Jae    BonneVersionDos

         Mov    ah,3
         Mov    bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,26
         Mov    bp,Offset MauvaisDos
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h

         Jmp    PrgF
BonneVersionDos:

         Mov    AX,5802h
         Int    21h
         Jnc    UtiliseUMB
         Mov    UMB,0FFh
UtiliseUMB:

         Mov    Ax,5803h
         Xor    Bx,Bx
         Int    21h                    ; Supprime Gestion UMB

         Mov    Ah,48h                 ; Reserve 128 K
	 Mov    BX,8192
	 Int    21h                    ; En Mémoire Basse

         Jnc    AssezMm
         Jmp    FinPrgP

AssezMm: Mov    DepSeg,Ax
         Mov    Ecran,Ax
         Mov    DecV,Ax
         Add    Ax,1000h
         Mov    SegANI,Ax

         Mov    Es,Ax
         Mov    Ah,1Bh
         Xor    Di,Di
         Xor    Bx,Bx
         Int    10h
         Cmp    Al,1Bh
         Je     SupFVd
         Jmp    FinPrgA
SupFVd:
         Push   Ds
         Lds    Si,[ES:DI]
	 Mov    Al,[DS:SI+2]
	 Test   Al,00001000b
	 Jne	SupMVd
         Pop    Ds
	 Jmp	FinPrgA
SupMVd:	 Pop	Ds

         Cld

         Call   Lib387

         Push   Offset Palette
         Push   Ecran
         Push   0
         Call   ChgPCX

         Mov    Ax,13h
         Int    10h

         Push   1                      ; Palette
         Push   Ecran
         Mov    Ax,Ecran
         Add    Ax,1000h
         Push   Ax
         Call   TransPCX

         Jmp    FInitialiseSys

FinPrgA: Mov    ah,3
         Mov    bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,22
         Mov    bp,Offset VideoMv
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h

         Jmp    PrgF

FinPrgP: Mov    ah,3
         Mov    bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,21
         Mov    bp,Offset MemF
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h

PRGF:    Cmp    XmsTaille,0
         Je     LXmsNetaitPasUtiliseeErreurXms

         Mov    Ah,0Ah
         Mov    Dx,XmsHandle
         Call   CS:XmsAd

LXmsNetaitPasUtiliseeErreurXms:
         PopA
         Mov    AX,4C00h
	 Int    21h

Process: Pop    ES
         Mov    ah,3
         Mov    bh,0
         Int    10h                    ; Pos Curseur

         Mov    BX,7
         Mov    CX,32
         Mov    bp,Offset ProcMv
         Mov    Ax,Ds
         Mov    Es,Ax
         Mov    Ax,1301h
         Int    10h

         PopA
         Mov    AX,4C00h
	 Int    21h