;*****************************
;Fonction speciale pour le GBF
;*****************************

IFDEF MACROGBF
ELSE
MACROGBF=0


;*******************************************
;Installe le nouveau gestionnaire de l'int 8
;*******************************************

 INIT_NEW_TIMER MACRO
   PUSH DS
   PUSHA
     MOV AX,3508H                      ;
     INT 21H                           ;Sauve l'adresse de l'int 8
     MOV AX,ES                         ;
     MOV WORD PTR [hold_int8],BX       ;
     MOV WORD PTR [hold_int8+2],AX     ;

     MOV AX,SEG NEW_TIMER              ;
     MOV DS,AX                         ;Fixe la nouvelle adresse de l'int 8
     MOV DX,OFFSET NEW_TIMER           ;
     MOV AX,2508H                      ;
     INT 21H                           ;
   POPA
   POP DS
 ENDM





;****************************************
;Restore l'ancien gestionnaire de l'int 8
;****************************************

 HOLD_TIMER MACRO
   PUSH DS
   PUSHA
    
     CLI
     MOV AL,36H                         ;
     OUT 43H,AL                         ;Fixe la fr‚quence d'interruption
                                        ;… 18.2.
     MOV AL,0FFH                        ;
     OUT 40H,AL                         ;
     OUT 40H,AL                         ;
     

     
     MOV DX,WORD PTR [hold_int8]        ;
     MOV AX,WORD PTR [hold_int8+2]      ;Restore l'ancienne adresse de l'int 8
     MOV DS,AX                          ;
     MOV AX,2508H                       ;
     INT 21H                            ;
     STI                                ;
    POPA
    POP DS
 ENDM


;*************************************************
;Apelle la fonction qui fixe la fr‚quence du timer
;et donc la fr‚quence d'appelle de l'int 8
;*************************************************

 FIXE_ECHANTILLONAGE MACRO ECHANT
  PUSH ECHANT
  CALL SR_FIXE_ECHANTILLONAGE
 ENDM



    .DATA
     hold_int8 DD 0        ;pour sauver l'adresse du gestionnaire original de l'int 8       

    .CODE

;***************************
;Nouvelle interruption timer
;***************************

    NEW_TIMER PROC FAR
     CLI                        ;interdit les interruptions materielles
     PUSHA                      ;empile tout les registres g‚n‚raux 
     PUSH DS                    ;empile le registre DS
     PUSH ES

     MOV AX,@DATA               ;DS=segment de donn‚e
     MOV DS,AX


     

     CMP Signal,1               ;Test si le signal s‚lectionn‚ est un triangle.
     JNE @NO_TRIANGLE           ;Si non passe ____________________
      MOV AX,TH                 ;                                 |
      CMP TIME,AX               ;                                 |
      JAE @TH_FINI2             ;                                 |
       MOV AX,time              ;SI time<TH                       |
       MOV BX,Vmax              ;                                 |
       SHL BX,1                 ;                                 |
       MUL BX                   ;AX=time*Vmax/TH+Voffset          |
       DIV TH                   ;                                 |
      JMP @CONT_SIG2            ;                                 |
      @TH_FINI2:                ;                                 |
       MOV AX,time              ;                                 |
       SUB AX,TH                ;SI time>TH                       |
       MOV BX,Vmax              ;                                 |
       SHL BX,1                 ;                                 |
       MUL BX                   ;                                 |
       DIV TB                   ;                                 |
       MOV BX,VMAX              ;                                 |
       SHL BX,1                 ;                                 |
       SUB BX,AX                ;                                 |
       MOV AX,BX                ;                                 |
      @CONT_SIG2:               ;                                 |
      MOV BX,Vmax               ;                                 |
      SHR BX,1                  ;                                 |
      SUB AX,BX                 ;                                 |
      MOV BX,Vmax               ;                                 |
      SHR BX,1                  ;                                 |
      SUB AX,BX                 ;                                 |
      ADD AX,127                ;                                 |
      ADD AX,VOffset            ;                                 |
      ECRIT_CAN AX              ;de AX … la carte                 |
     @NO_TRIANGLE:              ;                 <----------------
     



     CMP SIGNAL,10b             ;Test si le signal s‚lectionn‚ est un carr‚.
     JNE @NO_CARRE              ;si non passe _____________ 
      MOV AX,TH                 ;Si time inf‚rieur au      |    
      CMP TIME,AX               ;temp … l'‚tat haut        |
      JA @TH_FINI               ;BX=Voffset+Vmax           |
       MOV BX,Voffset           ;Si non                    |
       ADD BX,Vmax              ;BX=Voffset-Vmax           |
      JMP @CONT_SIG             ;                          |
      @TH_FINI:                 ;                          |
       MOV BX,Voffset           ;                          |
       SUB BX,Vmax              ;                          |
      @CONT_SIG:                ;                          |
      ADD BX,128                ;                          |
      ECRIT_CAN BX              ;Envoie la valeur          |
     @NO_CARRE:                 ;de BX … la carte      <----




     CMP SIGNAL,100b            ;Test si le signal s‚l‚ctionn‚  est un sinus.
     JNE @NO_SIN                ;Si non passe ________________
      MOV AX,TIME               ;                             |
      MOV BX,360                ;                             |
      MUL BX                    ;                             |
      DIV Periode               ;AX=Vmax*sin(time)+offset     |
      MOV DI,AX                 ;                             |
      SHL DI,1                  ;                             |
      ADD DI,Offset SIN         ;                             |
      MOV AX,DS:[DI]            ;                             |
      SUB AX,127                ;                             |
      MOV BX,Vmax               ;                             |
      IMUL BX                   ;                             |
      MOV BX,127                ;                             |
      IDIV BX                   ;                             |
      ADD AX,127                ;                             |
      ADD AX,Voffset            ;                             |
      ECRIT_CAN AX              ;Envoie la valeur             |
    @NO_SIN:                    ;de AX … la carte    <---------


    CMP INPUTON,0
    JE @NO_VISU
    CMP VISUP,0
    JNE @NO_VISU
     MOV DI,OFFSET[VISUP]+1
     ADD DI,TIME
     LIT_CAN
     MOV BYTE PTR DS:[DI],AL
    @NO_VISU:

     INC WORD PTR [TIME]        ;incr‚mente la variable time

     MOV AX,Periode             ;Si time>Nb de point 
     CMP TIME,AX                ;dans une p‚riode,
     JB @PERIODE_NOT_FINI       ;time=0
      MOV TIME,0                ;
      MOV VISUP,1               ;
     @PERIODE_NOT_FINI:         ;

     MOV AL,20H                 ;informe le contr“leur d'interruption
     OUT 20H,AL                 ;que l'interruption est termin‚e.

     POP ES
     POP DS                     ;D‚pile DS
     POPA                       ;D‚pile tous les registre g‚n‚raux
     STI                        ;Autorise les interruption mat‚rielle
    IRET                        ;Retour d'interruption.
    ENDP


   SR_FIXE_ECHANTILLONAGE PROC FAR
    PUSH BP
    MOV BP,SP
    PUSH AX
    PUSH DX
    PUSH BX

    CLI
     MOV AL,36H
     OUT 43H,AL
     
     MOV AX,34DCH
     MOV DX,12H
     MOV BX,[BP+6]
     DIV BX
     
     OUT 40H,AL
     
     MOV AL,AH
      3             3
        mem8              -     -     5     4             3


SETG/SETNLE - Set if