;********************
;Fonctions graphiques
;********************
    DOSSEG
    .MODEL LARGE
    .286

;**********
;Constantes
;**********



;********************************
;D‚claration des fonctions public
;********************************
    PUBLIC SR_PRINT_CHAR
    PUBLIC SR_PRINT_CHAIN
    PUBLIC SR_PRINT_NOMBRE_SIGNE
    PUBLIC SR_LIGNE

    PUBLIC CHAR_PTR
    EXTRN VIDEO_SEG:WORD

;***************************************
;Variables pour les fonctions graphiques
;***************************************
    .DATA

    CHAR_PTR DD 0

;*******************
;D‚but des fonctions
;*******************
    .CODE


;******************
;Ecrit un caract‚re
;******************

    SR_PRINT_CHAR PROC FAR
     PUSH BP
     MOV BP,SP
     PUSH DS
     PUSHA

      MOV AX,@DATA
      MOV DS,AX

      MOV DX,3C4H
      MOV AL,2
      OUT DX,AL


      
      MOV AX,[BP+6]
      XOR AH,AH
      SHL AX,3
      MOV SI,AX



      MOV AX,[BP+10]
      MOV BX,5
      MUL BX
      ADD AX,VIDEO_SEG    ;fixe le segment
      MOV ES,AX



      ADD SI,WORD PTR [CHAR_PTR]
      MOV AX,WORD PTR [CHAR_PTR+2]
      MOV DS,AX

      MOV CX,[BP+12]   ;fixe le plan de bit adr‚ss‚
      AND CL,3
      MOV AL,1
      SHL AL,CL
      MOV DX,3C5H
      OUT DX,AL

      MOV DI,[BP+12]   ;fixe l'offset
      SHR DI,2

      CLD
      MOV AH,[BP+8]          ;AH=couleur
      MOV CX,8
      @PCB0:
       PUSH CX
       MOV BH,10000000b
       MOV BL,00001000b
       LODSB

       MOV CX,4
       @PCB4:
        PUSH CX

        TEST AL,BH
        JZ @PCB1
         MOV ES:[DI],AH
        @PCB1:

        TEST AL,BL
        JZ @PCB2
         MOV ES:[DI+1],AH
        @PCB2:

        PUSH AX
         SHR BX,1
         IN AL,DX
         SHL AL,1
         TEST AL,10000b
         JZ @PCB3
          INC DI
          MOV AL,1
         @PCB3:
         OUT DX,AL
        POP AX

        POP CX
       LOOP @PCB4

       ADD DI,79
       POP CX
      LOOP @PCB0



     POPA
     POP DS
     POP BP
    RETF 8
    ENDP


;******************************
;Ecrit une chaine de caract‚res
;******************************

    SR_PRINT_CHAIN PROC FAR
     PUSH BP
     MOV BP,SP
     PUSH SI
     PUSH DS
     

      MOV AX,@DATA
      MOV DS,AX
      MOV SI,[BP+6]

       CLD
       LODSB
       CMP AL,0
      JE @CHAIN_FINI
      @DEPART_CHAIN:
       PUSH [BP+12]
       PUSH [BP+10]
       PUSH [BP+8]
       PUSH AX
       CALL SR_PRINT_CHAR

       CLD
       LODSB
       CMP AL,0
      JE @CHAIN_FINI

       CMP AL,32
       JNE @PCHAIN0
        ADD WORD PTR [BP+12],3  ;Si c'est un espace l'ecart et moin grand
       JMP @DEPART_CHAIN
       @PCHAIN0:

       TEST AL,32
       JNZ @PCHAIN1
        CMP AL,91
        JA @PCHAIN1       ;si symbole sp‚cial  ne pas agrandir l'ecart
         ADD WORD PTR [BP+12],1 ;SI majuscule agrandir l'‚cart
       @PCHAIN1:
        ADD WORD PTR [BP+12],7 ; FIXER l'ecart
       @PCHAIN2:

       CMP AL,57
       JA @PCHAIN3
       CMP AL,48
       JB @PCHAIN3
        ADD WORD PTR [BP+12],1 ;nombre? agrandir l'ecart
       @PCHAIN3:

       JMP @DEPART_CHAIN
      @CHAIN_FINI:

     
     POP DS
     POP SI
     POP BP
    RETF 8
    ENDP

;*********************
;Ecrit un nombre sign‚
;*********************

    SR_PRINT_NOMBRE_SIGNE PROC FAR
     PUSH BP
     MOV BP,SP
     PUSH DX
     PUSH BX

     MOV AX,[BP+6]          ;Affiche le signe et calcul la valeur absolue
     CMP AX,0
     JNS @NB_NOT_NEG
      PUSH [BP+12]
      PUSH [BP+10]
      PUSH [BP+8]
      PUSH 45
      CALL SR_PRINT_CHAR
      NEG WORD PTR [BP+6]          
     @NB_NOT_NEG:
      ADD WORD PTR [BP+12],8*4+7

     MOV BX,10
     MOV CX,5                ;5 chiffres a afficher
     @PRINT_NB0:
      MOV AX,[BP+6]
      XOR DX,DX
      DIV BX
      MOV [BP+6],AX          ;non
      ADD DX,48

      PUSH [BP+12]           ;empile X
      PUSH [BP+10]           ;empile Y
      PUSH [BP+8]            ;empile couleur
      PUSH DX                ;empile caractere 
      CALL SR_PRINT_CHAR     ;Affiche un chiffre
      SUB WORD PTR [BP+12],8          ;d‚cr‚mente X

     LOOP @PRINT_NB0


     POP BX
     POP DX
     POP BP
    RETF 8
    ENDP

;****************
; Trace une ligne
;****************
    ALIGN WORD
    INCY DW 0
    DELTAX DW 0
    DELTAY DW 0
    PBD    DB 0
    PBF    DB 0
    OFSfin DW 0

    SR_LIGNE PROC FAR
     PUSH BP
     MOV BP,SP
     PUSH ES
     PUSHA

      ;CALCUL DELTAX 

      MOV AX,[BP+10]          ;AX=X2
      SUB AX,[BP+14]          ;AX=X2-X1
      JNS @X2SUPX1            ;SI X2<X1
       NEG AX                  ;DELTAX=-DELTAX
       MOV BX,[BP+10]
       XCHG BX,[BP+14]
       MOV [BP+10],BX

       MOV BX,[BP+12]
       XCHG BX,[BP+8]
       MOV [BP+12],BX
      @X2SUPX1:
      INC AX
      MOV DELTAX,AX


      ;CALCUL DELTAY ET INCY

      MOV INCY,80             ;INCY=largeur de l'ecran/4(mode lineaire)
      MOV AX,[BP+8]           ;AX=Y2
      SUB AX,[BP+12]          ;AX=Y2-Y1
      JNS @Y2SUPY1            ;SI Y2<Y1
       NEG INCY                ;INCY=-INCY
       NEG AX                  ;DELTAY=-DELTAY
      @Y2SUPY1:
      INC AX
      MOV DELTAY,AX


      ;CALCUL L'OFFSET ET LE PLAN DE BITS DE DEPART

      XOR AH,AH
      MOV CX,[BP+14]    ;calcul le plan de bits de depart
      AND CL,11B
      MOV AL,1
      SHL AL,CL
      MOV AH,AL
      SHL AH,4
      OR AL,AH
      MOV PBD,AL
      
      MOV AX,[BP+12]    ;et l'offset de depart
      MOV BX,80
      MUL BX
      MOV CX,[BP+14]    
      SHR CX,2
      ADD CX,AX
      MOV DI,CX

      ;CALCUL L'OFFSET ET LE PLAN DE BITS DE FIN

      XOR AH,AH
      MOV CX,[BP+10]    ;calcul le plan de bits de fin
      AND CL,11B
      MOV AL,1
      SHL AL,CL
      MOV AH,AL
      SHL AH,4
      OR AL,AH
      MOV PBF,AL
      
      MOV AX,[BP+8]    ;et l'offset de fin
      MOV BX,80
      MUL BX
      MOV CX,[BP+10]    
      SHR CX,2
      ADD CX,AX
      MOV OFSfin,CX

      ;FIXE ES SUR LE SEGMENT VIDEO

      MOV AX,0A000H
      MOV ES,AX

      ;DESSINE LA LIGNE  (vitesse non optimis‚e)

      MOV DX,03C4H           ;adresse le registre MAP MASK du sequenceur
      MOV AL,2
      OUT DX,AL
      INC DX
      MOV AL,PBD             ;fixe le plan de bits activ‚
      OUT DX,AL

      MOV AH,[BP+6]          ;AL=couleur
      MOV AL,PBD

      MOV BX,DELTAX          ;BX=DELTAX-DELTAY
      SUB BX,DELTAY
      JS @INCY

       @INCX:
        MOV ES:[DI],AH
        ROL AL,1
        ADC DI,0
        OUT DX,AL
        SUB BX,DELTAY
       JG @INCX

       CMP DI,OFSfin
       JNE @INCY
       CMP AL,PBF
       JNE @INCY
       JMP @LIGNE_FINI

       @INCY:
        MOV ES:[DI],AH
        ADD DI,INCY
        ADD BX,DELTAX
       JL @INCY

       CMP DI,OFSfin
       JNE @INCX
       CMP AL,PBF
       JNE @INCX
      JMP @LIGNE_FINI

     @LIGNE_FINI:


     POPA
     POP ES
     POP BP
    RETF 10
    ENDP

   END

