home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / noyau / principa.asm < prev    next >
Assembly Source File  |  1994-05-25  |  24KB  |  860 lines

  1. ;
  2. ;   Principa.asm
  3. ;
  4. ;   Processus principal & tous ses processus fils
  5. ;
  6. ;   Noyau Multitache .
  7. ;
  8. ;  ART    OF CODE
  9.  
  10. .286
  11. .MODEL SMALL,OS_DOS
  12.  
  13. INCLUDE dos.inc
  14. INCLUDE types.inc
  15. INCLUDE const.inc
  16. INCLUDE etats.inc
  17. INCLUDE descript.inc
  18. INCLUDE semphor.inc
  19. INCLUDE process.inc
  20. INCLUDE gestlist.inc
  21. INCLUDE donnees.inc
  22. INCLUDE code.inc
  23. INCLUDE tampon.inc
  24.  
  25.  
  26. ; définition des fonctions de gestion d'écran.
  27. ; fonctions assez vielles ( avril 92 ) et certainement mal programmées.
  28. EXTERNDEF Trace_Cadre : NEAR ; Attention, procédure non réentrante
  29. EXTERNDEF Clear_Screen : NEAR
  30. EXTERNDEF Affiche_Chaine : NEAR
  31.  
  32.  
  33.  
  34. ; déclaration des segments de pile de chaque processus
  35.  
  36. PilePrincipal SEGMENT WORD 'STACK'  ; pile privée du processus
  37.     WORD (DimPile-NbRegs) DUP (?)
  38. PUBLIC SP_PilePrincipal
  39. SP_PilePrincipal LABEL WORD        ; sommet actuel de la pile privée
  40.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  41.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  42.     WORD OFFSET Principal        ; point d'entrée
  43. PilePrincipal ENDS
  44.  
  45. PileGestEcran SEGMENT WORD 'STACK'  ; pile privée du processus
  46.     WORD (DimPile-NbRegs) DUP (?)
  47. SP_PileGestEcran LABEL WORD        ; sommet actuel de la pile privée
  48.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  49.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  50.     WORD OFFSET GestEcran        ; point d'entrée
  51. PileGestEcran ENDS
  52.  
  53. Pileprocess SEGMENT WORD 'STACK'    ; pile privée du processus
  54.     WORD (DimPile-NbRegs) DUP (?)
  55. SP_Pileprocess LABEL WORD        ; sommet actuel de la pile privée
  56.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  57.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  58.     WORD OFFSET process         ; point d'entrée
  59. Pileprocess ENDS
  60.  
  61. Pileprocess2 SEGMENT WORD 'STACK'   ; pile privée du processus
  62.     WORD (DimPile-NbRegs) DUP (?)
  63. SP_Pileprocess2 LABEL WORD        ; sommet actuel de la pile privée
  64.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  65.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  66.     WORD OFFSET process2        ; point d'entrée
  67. Pileprocess2 ENDS
  68.  
  69. Pileprocess3 SEGMENT WORD 'STACK'   ; pile privée du processus
  70.     WORD (DimPile-NbRegs) DUP (?)
  71. SP_Pileprocess3 LABEL WORD        ; sommet actuel de la pile privée
  72.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  73.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  74.     WORD OFFSET process3        ; point d'entrée
  75. Pileprocess3 ENDS
  76.  
  77. PileProcess4 SEGMENT WORD 'STACK'   ; pile privée du processus
  78.     WORD (DimPile-NbRegs) DUP (?)
  79. SP_PileProcess4 LABEL WORD        ; sommet actuel de la pile privée
  80.     WORD (NbRegs - 2)      DUP (?)   ; valeur initiale des registres du µp
  81.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  82.     WORD OFFSET Process4        ; point d'entrée
  83. PileProcess4 ENDS
  84.  
  85. PileProcess5 SEGMENT WORD 'STACK'   ; pile privée du processus
  86.     WORD (DimPile-NbRegs) DUP (?)
  87. SP_PileProcess5 LABEL WORD        ; sommet actuel de la pile privée
  88.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  89.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  90.     WORD OFFSET Process5        ; point d'entrée
  91. PileProcess5 ENDS
  92.  
  93. PileProcess6 SEGMENT WORD 'STACK'   ; pile privée du processus
  94.     WORD (DimPile-NbRegs) DUP (?)
  95. SP_PileProcess6 LABEL WORD        ; sommet actuel de la pile privée
  96.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  97.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  98.     WORD OFFSET Process6        ; point d'entrée
  99. PileProcess6 ENDS
  100.  
  101. PileProducteur SEGMENT WORD 'STACK' ; pile privée du processus
  102.     WORD (DimPile-NbRegs) DUP (?)
  103. SP_PileProducteur LABEL WORD        ; sommet actuel de la pile privée
  104.     WORD (NbRegs - 2)      DUP (?)   ; valeur initiale des registres du µp
  105.     WORD ETAT_INITIAL            ; valeur initiale du mot d'état
  106.     WORD OFFSET Producteur        ; point d'entrée
  107. PileProducteur ENDS
  108.  
  109. PileConsommateur SEGMENT WORD 'STACK' ; pile privée du processus
  110.     WORD (DimPile-NbRegs) DUP (?)
  111. SP_PileConsommateur LABEL WORD        ; sommet actuel de la pile privée
  112.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  113.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  114.     WORD OFFSET Consommateur        ; point d'entrée
  115. PileConsommateur ENDS
  116.  
  117. PileMonHorloge SEGMENT WORD 'STACK' ; pile privée du processus
  118.     WORD (DimPile-NbRegs) DUP (?)
  119. SP_PileMonHorloge LABEL WORD        ; sommet actuel de la pile privée
  120.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  121.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  122.     WORD OFFSET MonHorloge        ; point d'entrée
  123. PileMonHorloge ENDS
  124.  
  125. PileBalle SEGMENT WORD 'STACK'        ; pile privée du processus
  126.     WORD (DimPile-NbRegs) DUP (?)
  127. SP_PileBalle LABEL WORD            ; sommet actuel de la pile privée
  128.     WORD (NbRegs - 2)     DUP (?)   ; valeur initiale des registres du µp
  129.     WORD ETAT_INITIAL               ; valeur initiale du mot d'état
  130.     WORD OFFSET Balle            ; point d'entrée
  131. PileBalle ENDS
  132.  
  133.  
  134. ; Données concernant le Timer Système pour le processus d'affichage
  135. ; de l'horloge.
  136.  
  137. DonneesTimer SEGMENT AT 0040h
  138.     org 006Ch
  139.     TIMER_LOW       WORD ?
  140.     TIMER_HIGH        WORD ?
  141. DonneesTimer ENDS
  142.  
  143.  
  144. .DATA
  145.  
  146. ; définition des Descripteurs de Processus
  147.  
  148. pGestEcran    PROCESSUS <{,,,TypeProcessus,SUSPENDU,129},OFFSET SP_PileGestEcran,PileGestEcran,NIL>
  149. pProcess      PROCESSUS <{,,,TypeProcessus,SUSPENDU,131},OFFSET SP_Pileprocess,Pileprocess,NIL>
  150. pProcess2     PROCESSUS <{,,,TypeProcessus,SUSPENDU,131},OFFSET SP_Pileprocess2,Pileprocess2,NIL>
  151. pProcess3     PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_Pileprocess3,Pileprocess3,NIL>
  152. pProcess4     PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_PileProcess4,PileProcess4,NIL>
  153. pProcess5     PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_PileProcess5,PileProcess5,NIL>
  154. pProcess6     PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_PileProcess6,PileProcess6,NIL>
  155. pProducteur   PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_PileProducteur,PileProducteur,NIL>
  156. pConsommateur PROCESSUS <{,,,TypeProcessus,SUSPENDU,136},OFFSET SP_PileConsommateur,PileConsommateur,NIL>
  157. pMonHorloge   PROCESSUS <{,,,TypeProcessus,SUSPENDU,1},OFFSET SP_PileMonHorloge,PileMonHorloge,NIL>
  158. pBalle          PROCESSUS <{,,,TypeProcessus,SUSPENDU,1},OFFSET SP_PileBalle,PileBalle,NIL>
  159.  
  160. ; Déclaration des sémaphores
  161.  
  162. Synchro1       SEMAPHORE    <>  ; sémaphore de synchronisation
  163. Synchro2       SEMAPHORE    <>  ; sémaphore de synchronisation
  164. sPrincipal       SEMAPHORE    <>  ; sémaphore de déblocage du processus principal
  165. DosBios        SEMAPHORE    <>  ; sémaphore d'exclusion mutuelle concernant le DOS
  166. mutex           SEMAPHORE    <>  ; sémaphore d'exclusion mutuelle concernant le Tampon
  167. PlaceLibre       SEMAPHORE    <>  ; sémaphore concernant le buffer circulaire
  168. CarDisponible       SEMAPHORE    <>  ; sémaphore concernant le buffer circulaire
  169.  
  170.  
  171. PUBLIC sHorloge ; sémaphores commandant l'execution de ces deux processus
  172. ; ces sémaphores sont préinitialisés. Donc pas de problèmes de démarrage.
  173. sHorloge SEMAPHORE <{OFFSET sHorloge,OFFSET sHorloge,,TypeSemaphore,OCCUPE,INFINI},0>
  174. sBalle SEMAPHORE <{OFFSET sBalle,OFFSET sBalle,,TypeSemaphore,OCCUPE,INFINI},0>
  175.  
  176.  
  177. ; Déclaration des affichages
  178.  
  179. Chaine1 DB "NOYAU MULTITACHE PREEMPTIF Version 1.0",0
  180. Chaine2 DB "Par the EQUALIZER from The ART OF CODE !!!",0
  181. ChainePro1 DB "Processus N°1 ( priorité 131 ) synchro ... ",0
  182. ChainePro2 DB "Processus N°2 ( priorité 131 ) synchro ... ",0
  183. ChainePro3 DB "Processus N°3 ( priorité 136 )............ ",0
  184. ChainePro4 DB "Processus N°4 ( priorité 136 )............ ",0
  185. ChainePro5 DB "Processus N°5 ( priorité 136 )............ ",0
  186. ChainePro6 DB "Processus N°6 ( priorité 136 )............ ",0
  187. ChaineProducteur DB "Veuillez tapez votre phrase suivie de [entrée]:",0
  188.  
  189. ; Déclaration du tampon d'echange entre le Producteur et le Consommateur
  190.  
  191. BufferClavier BYTE 32 DUP (?)
  192. LeTampon TAMPON <OFFSET BufferClavier,OFFSET BufferClavier,OFFSET BufferClavier,OFFSET BufferClavier+32,OFFSET Ajoute,OFFSET Retire>
  193.  
  194. ; Données concernant la petite balle qui rebondit
  195. x    WORD ?    ; coordonnées de la balle
  196. y    WORD ?
  197. x1   WORD ?    ; coordonnées des limites du rectangle
  198. y1   WORD ?    ; dans lequel évolue la balle
  199. x2   WORD ?
  200. y2   WORD ?
  201. devx WORD ?    ; variables de direction de la balle : 1 = droite, -1 = gauche
  202. devy WORD ?    ; 1 = bas , -1 = haut
  203.  
  204.  
  205.  
  206. .CODE
  207.  
  208.  
  209. ; Attention ces deux procédures doivent s'executer en exclusion mutuelle
  210. ; prodédure d'ajout dans un buffer circulaire pointé par ds:si
  211. ; on ajoute l'octet AL
  212. Ajoute PROC
  213.     push ax
  214.     push si
  215.     ASSUME DS:@data;es:Nothing
  216.     mov SI,(TAMPON PTR [si]).LaQueue
  217.     mov [si],al             ; on place AL en queue
  218.     pop si
  219.     mov ax,(TAMPON PTR [si]).LaQueue
  220.     inc ax                ; on incrémente Queue
  221.     cmp ax,(TAMPON PTR [si]).LaFin    ; si on arrive à la fin, on retourne
  222.     jne Ajoute_Suite            ; au début
  223.     mov ax,(TAMPON PTR [si]).Debut
  224. Ajoute_Suite:
  225.     mov (TAMPON PTR [si]).LaQueue,ax
  226.     pop ax
  227.     RET
  228. Ajoute ENDP
  229.  
  230.  
  231.  
  232. ; Procédure de retrait d'une valeur du buffer circulaire dans AL
  233. Retire PROC
  234.     push si
  235.     ASSUME DS:@data;es:Nothing
  236.     mov SI,(TAMPON PTR [si]).Tete   ; on récupère le premier caractère ( FIFO )
  237.     mov al,[SI]
  238.     pop si
  239.     push ax
  240.     mov ax,(TAMPON PTR [si]).Tete   ; on incrémente la tête
  241.     inc ax
  242.     cmp ax,(TAMPON PTR [si]).LaFin  ; si arrivé à la fin, on saute au début.
  243.     jne Retire_Suite
  244.     mov ax,(TAMPON PTR [si]).Debut
  245. Retire_Suite:
  246.     mov (TAMPON PTR [si]).Tete,ax
  247.     pop ax
  248.     RET                 ; et voila.
  249. Retire ENDP
  250.  
  251.  
  252. ; procédure de suicide d'un processus
  253. Suicide PROC NEAR
  254.      mov si,[EnCours]        ; on tue le processus
  255.      mov (DESCRIPTEUR PTR [si]).Etat,TERMINE
  256.      call dispatcher
  257. Suicide ENDP
  258.  
  259.  
  260. ; Procedure qui fait rebondir une petite balle
  261. ; processus sans prétention ni optimisation, juste pour montrer l'aspect
  262. ; multitache.
  263. Balle PROC
  264.     mov ax,@data
  265.     mov ds,ax
  266.     mov ax,0B800h
  267.     mov es,ax
  268.     ASSUME DS:@data;es:Nothing
  269.     mov word ptr [x1],10    ; on sauvegarde les limites
  270.     mov word ptr [x2],69    ; du rectangle Hôte.
  271.     mov word ptr [y1],20
  272.     mov word ptr [y2],24
  273.     mov word ptr [x],11     ; coordonnées de départ
  274.     mov word ptr [y],21
  275.     mov word ptr [devx],1   ; directions de départ
  276.     mov word ptr [devy],1
  277.  
  278.     mov di,2*11+160*21        ;di=(11,21)
  279. BoucleBalle:
  280.     lea si,sBalle
  281.     Call p            ; on bloque le processus
  282.     mov si,di            ; on sauvegarde l'ancienne position de la balle
  283.  
  284.     mov ax,[x]            ; on effectue le déplacement de la balle
  285.     add ax,word ptr [devx]
  286.     cmp ax,word ptr [x2]    ; débordement à gauche ?
  287.     jne suite_x2        ; non, on continue
  288.     sub ax,2            ; on change la direction
  289.     neg word ptr [devx]
  290.     jmp suite_x3        ; on continue
  291. suite_x2:
  292.     cmp ax,word ptr [x1]    ; débordement à droite
  293.     jne suite_x3
  294.     add ax,2            ; idem
  295.     neg word ptr [devx]
  296. suite_x3:
  297.     mov word ptr [x],ax     ; on sauvegarde la nouvelle valeur de X
  298.  
  299.     mov ax,[y]            ; on fait la même chose pour Y
  300.     add ax,word ptr [devy]
  301.     cmp ax,word ptr [y2]
  302.     jne suite_y2
  303.     sub ax,2
  304.     neg word ptr [devy]
  305.     jmp suite_y3
  306. suite_y2:
  307.     cmp ax,word ptr [y1]
  308.     jne suite_y3
  309.     add ax,2
  310.     neg word ptr [devy]
  311. suite_y3:
  312.     mov word ptr [y],ax     ; Sauvegarde de Y
  313.  
  314.     mov di,[x]            ; calcul du nouveau di=(X,Y)
  315.     shl di,1
  316.     xor dx,dx
  317.     mov ax,[y]
  318.     mov bx,160
  319.     mul bx
  320.     add di,ax             ; di=2*x+160*y ( 2 octets par caractères )
  321.     mov byte ptr es:[si],' ' ; on efface le précédent
  322.     mov byte ptr es:[di],'' ; on affiche la balle à son nouvel emplacement
  323.  
  324.     jmp BoucleBalle         ; on boucle ad eternam
  325.  
  326. ; Ce processus étant pour la majeure partie de son temps bloqué dans la
  327. ; file d'attente du sémaphore, lorsque les autres processus auront fini,
  328. ; et que le noyau reprendra la main, il terminera lui même ce processus
  329. ; par le biais de HORLOGE qui rétablira l'ancien vecteur d'interruption 08h
  330. Balle ENDP
  331.  
  332.  
  333. ; Processus d'affichage d'une horloge en temps réel à l'ecran
  334. MonHorloge PROC
  335.  
  336.      mov ax,0B800h
  337.      mov es,ax
  338.      mov bp,0
  339. BoucleHorloge:
  340.      mov ax,@data
  341.      mov ds,ax
  342.      ASSUME DS:@data
  343.      lea si,sBalle    ; on débloque le processus 'Balle'
  344.      call v
  345.      lea si,sHorloge    ; on attend que l'interruption Timer nous débloque
  346.      call p
  347.      mov ax,DonneesTimer
  348.      mov ds,ax
  349.      ASSUME DS:DonneesTimer
  350.      MOV AX,[TIMER_LOW] ; prise en compte de la valeur TIMER_LOW
  351.      xor dx,dx
  352.      mov bx,1093    ; on la divise par 1093 ( en effet, Timer_low
  353.      div bx        ; arrive à 65535 à chaque nouvelle heure donc
  354.      mov di,22*160+8    ; TimerLow / 1093 => Minutes
  355.      mov cx,2
  356.      CALL AFFDEC    ; on affiche les minutes
  357.      mov di,22*160+6
  358.      cmp bp,9        ; petit test pour savoir si on affiche les ':'
  359.      jae deuxpoints    ; oui
  360.      mov byte ptr es:[di],' '
  361.      jmp deuxpoints2    ; non, on affiche ' ' et on saute
  362. deuxpoints:
  363.      mov byte ptr es:[di],':'
  364. deuxpoints2:
  365.      mov di,22*160+2    ; on affiche tel quel l'heure
  366.      MOV AX,[TIMER_HIGH]
  367.      cmp ax,24        ; j'ai remarqué lors d'essais tres poussés (si!) que
  368.      jne pas24        ; entre 23:59 et 00:00, durant quelques secondes,
  369.      xor ax,ax        ; on avait : 24:00 ( serait-ce un bug de ma part ? ou
  370.             ; un temps nécessaire à la machine pour prendre en
  371.             ; compte le changement de journée ?)
  372. pas24:
  373.      CALL AFFDEC    ; on l'affiche
  374.      inc bp        ; bp est juste un compteur qui permet de temporiser
  375.      cmp bp,18        ; le clignotement des ':'
  376.      jne BoucleHorloge
  377.      mov bp,0
  378.      jmp BoucleHorloge    ; on boucle
  379.  
  380. ; MonHorloge,tous comme Balle, est terminé par pHorloge lorsque celui-ci
  381. ; rétablit l'ancien gestionnaire d'interruption.
  382.  
  383. MonHorloge ENDP
  384.  
  385.  
  386. ; Et voici sa majesté le processus Principal
  387. Principal PROC
  388.      mov ax,@data
  389.      mov ds,ax
  390.      ASSUME ds:@data
  391.  
  392. ; On initialise tous les sémaphores
  393. ; La nouvelle version d'InitVide initialise l'etat à OCCUPE et
  394. ; la priorité à INFINI
  395.  
  396.      lea si,sPrincipal
  397.      mov (SEMAPHORE PTR [si]).Compteur,0
  398.      call InitVide
  399.      lea si,Synchro1
  400.      mov (SEMAPHORE PTR [si]).Compteur,0
  401.      call InitVide
  402.      lea si,Synchro2
  403.      mov (SEMAPHORE PTR [si]).Compteur,0
  404.      call InitVide
  405.      lea si,DosBios
  406.      mov (SEMAPHORE PTR [si]).Compteur,1 ; exclusion mutuelle
  407.      call InitVide
  408.      lea si,mutex
  409.      mov (SEMAPHORE PTR [si]).Compteur,1 ; idem
  410.      call InitVide
  411.      lea si,PlaceLibre
  412.      mov (SEMAPHORE PTR [si]).Compteur,32   ; 32 places libres
  413.      call InitVide
  414.      lea si,CarDisponible
  415.      mov (SEMAPHORE PTR [si]).Compteur,0    ; pas de caractères dispo pour
  416.      call InitVide                ; l'instant
  417.  
  418. ; On place tous les processus en queue d'exploitation
  419.  
  420.  
  421.      lea bx,pProcess        ; on place tous les DdP dans
  422.      call eligible        ; la queue d'exploitation
  423.      lea bx,pProcess2
  424.      call eligible
  425.      lea bx,pProcess3
  426.      call eligible
  427.      lea bx,pProcess4
  428.      call eligible
  429.      lea bx,pProcess5
  430.      call eligible
  431.      lea bx,pProcess6
  432.      call eligible
  433.      lea bx,pGestEcran
  434.      call eligible
  435.      lea bx,pProducteur
  436.      call eligible
  437.      lea bx,pConsommateur
  438.      call eligible
  439.      lea bx,pMonHorloge
  440.      call eligible
  441.      lea bx,pBalle
  442.      call eligible
  443.  
  444.  
  445.      lea si,sPrincipal    ; là, Principal attend la fin de tous ces fils.
  446.      mov cx,9
  447. attendre:
  448.      call p
  449.      loop attendre
  450.  
  451. ; Arrivé à ce stade, les 9 processus fils ont fini leur travail
  452. ; MonHorloge et Balle sont coincés momentanément dans leur sémaphore
  453. ; On termine.
  454.  
  455.      call Suicide ; Asta la vista baby !
  456.  
  457. Principal ENDP
  458.  
  459.  
  460. ; Voici le processus Producteur qui envoie toutes les touches tapées
  461. ; dans le buffer circulaire
  462. Producteur PROC
  463.  
  464.      mov ax,@data
  465.      mov ds,ax
  466.      ASSUME ds:@data
  467.  
  468.      lea si,ChaineProducteur
  469.      mov di,24+12*160
  470.      call Affiche_Chaine ; on affiche l'invite.
  471.  
  472. ProdBoucle:
  473.      lea si,PlaceLibre    ; on attend qu'il y ait de la place dans le buffer
  474.      call p
  475.  
  476. AttendreTouche:
  477.      lea si,DosBios
  478.      mov ah,06    ; fonction du dos, voir si une touche est frappée.
  479.      mov dl,255 ; entrée ( paramètre de la fonction)
  480.      call p    ; exclusion mutuelle pour Dos & Bios
  481.        int 21h
  482.      call v
  483.      jz AttendreTouche ; ZF=1 si aucune touche, sinon AL = Code ASCII
  484.  
  485.      lea si,mutex   ; on place la touche dans le buffer
  486.      call p
  487.     lea si,LeTampon
  488.     call (TAMPON PTR [si]).Ajouter
  489.      lea si,mutex
  490.      call v
  491.  
  492.      lea si,CarDisponible   ; on signale au consommateur qu'il a du boulot
  493.      call v
  494.  
  495.      cmp al,0Dh         ; a-t-on appuyé sur Return ?
  496.      jne ProdBoucle        ; non, on continue
  497.  
  498.      lea si,sPrincipal        ; si oui, on termine
  499.      call v
  500.  
  501.      call Suicide
  502.  
  503. Producteur ENDP
  504.  
  505.  
  506. ; processus consommateur : gestion des caractères placés dans le buffer
  507. ;               circulaire.
  508. Consommateur PROC
  509.  
  510.      mov ax,@data
  511.      mov ds,ax
  512.      ASSUME ds:@data
  513.      mov ax,0B800h
  514.      mov es,ax
  515.      ASSUME es:Nothing
  516.  
  517.      mov di,24+13*160    ; départ de l'affichage (12,13)
  518.  
  519. AttendreTampon:
  520.      lea si,CarDisponible   ; on attent le boulot
  521.      call p
  522.  
  523.      lea si,mutex        ; on extrait le caractère de tete
  524.      call p
  525.     lea si,LeTampon
  526.     call (TAMPON PTR [si]).Retirer
  527.      lea si,mutex
  528.      call v
  529.  
  530.      lea si,PlaceLibre        ; on signale la place libérée
  531.      call v            ; au producteur
  532.  
  533.      cmp al,0Dh         ; Return ?
  534.      je finConso        ; oui, on termine
  535.  
  536.      cmp al,08            ; a-t'on appuyé sur Backspace
  537.      jne pas_del        ; non, on saute
  538.      sub di,2               ; si oui, on efface le caractère précédent
  539.      mov byte ptr es:[di],' '
  540.      jmp del
  541. pas_del:
  542.      mov es:[di],al        ; on affiche le caractère
  543.      add di,2
  544. del:
  545.  
  546.      jmp AttendreTampon     ; et on continue ....
  547.  
  548. finConso:
  549.      lea si,sPrincipal        ; signale à Principal qu'un de ses fistons
  550.      call v            ; va mourrir
  551.  
  552.      call Suicide        ; et hop !
  553.  
  554. Consommateur ENDP
  555.  
  556.  
  557. GestEcran PROC    ; Processus d'affichage d'un bel écran tout joli !!!
  558.      mov ax,@data
  559.      mov ds,ax
  560.      ASSUME ds:@data
  561.  
  562.      call Clear_Screen    ; on efface l'écran.
  563.  
  564.      mov ah,10        ;  on affiche un cadre (10,6)->(70,19)
  565.      mov al,6        ;
  566.      mov bh,70        ;  ( Fenètre principale. )
  567.      mov bl,19        ;
  568.      mov dx,23        ; d'attribut 23
  569.      call Trace_Cadre    ;
  570.  
  571.      mov ah,1        ; on affiche un cadre (1,22)->(7,24)
  572.      mov al,22        ;
  573.      mov bh,7        ; ( Fenètre où sera affichée l'horloge. )
  574.      mov bl,24        ;
  575.      mov dx,5Fh     ; attribut = 5Fh
  576.      call Trace_Cadre    ;
  577.  
  578.      mov ah,10        ; Encore un cadre (10,21)->(70,25)
  579.      mov al,21        ;
  580.      mov bh,70        ;   ( Fenètre contenant la balle )
  581.      mov bl,25        ;
  582.      mov dx,26        ; attribut = 26
  583.      call Trace_Cadre    ;
  584.  
  585.      lea si,ChainePro1    ; on affiche les chaines de caractères
  586.      mov di,24+6*160
  587.      call Affiche_Chaine
  588.  
  589.      lea si,ChainePro2
  590.      mov di,24+7*160
  591.      call Affiche_Chaine
  592.  
  593.      lea si,ChainePro3
  594.      mov di,24+8*160
  595.      call Affiche_Chaine
  596.  
  597.      lea si,ChainePro4
  598.      mov di,24+9*160
  599.      call Affiche_Chaine
  600.  
  601.      lea si,ChainePro5
  602.      mov di,24+10*160
  603.      call Affiche_Chaine
  604.  
  605.      lea si,ChainePro6
  606.      mov di,24+11*160
  607.      call Affiche_Chaine
  608.  
  609.      ; on trace le cadre du haut, taille et centrage automatique sur la chaine
  610.      ; la plus longue ( Chaine2 ), grace à SIZEOF
  611.  
  612.      mov ah,((80-SIZEOF Chaine2)/2)-2
  613.      mov al,1
  614.      mov bh,((80-SIZEOF Chaine2)/2)+(SIZEOF Chaine2)+2
  615.      mov bl,4
  616.      mov dx,71
  617.      call Trace_Cadre ; on trace un cadre
  618.  
  619.      ; et on affiche les deux chaines dans le cadre ( centrée également )
  620.      lea si,Chaine1
  621.      mov di,2*((80-SIZEOF Chaine1)/2)+160
  622.      call Affiche_Chaine
  623.      lea si,Chaine2
  624.      mov di,2*((80-SIZEOF Chaine2)/2)+320
  625.      call Affiche_Chaine
  626.  
  627.      lea si,sPrincipal    ; c'est fait, bye bye ....
  628.      call v
  629.  
  630.      call Suicide
  631.  
  632. GestEcran ENDP
  633.  
  634.  
  635. ; processus numéro 1
  636. ; Ce processus est un compteur qui est synchronisé avec le processus 2
  637. process PROC
  638.      mov ax,@data
  639.      mov ds,ax
  640.      ASSUME ds:@data
  641.  
  642.      mov ax,0B800h
  643.      mov es,ax
  644.      mov di,57*2+160*6    ; ( affichage en (57,6))
  645.      mov cx,5        ; on effectue 5 fois le comptage
  646. Bcl1:
  647.      mov ax,0
  648. Boucle:
  649.     push cx
  650.     mov cx,9        ; on affiche ax sur 9 chiffres.
  651.     call Affdec
  652.     pop cx
  653.     inc ax
  654.     cmp ax,50000
  655.     jbe Boucle        ; on boucle
  656.     lea si,Synchro1
  657.     call v        ; on signale au process2 qu'il peut commencer
  658.     lea si,Synchro2    ; attend qu'il ait fini pour continuer.
  659.     call p
  660.     loop Bcl1
  661.  
  662.     lea si,sPrincipal
  663.     call v
  664.  
  665.     call Suicide
  666.  
  667. process ENDP
  668.  
  669. ; Voici le processus associé au processus 1
  670. process2 PROC
  671.     pusha
  672.      mov ax,@data
  673.      mov ds,ax
  674.      ASSUME ds:@data
  675.      mov ax,0B800h
  676.      mov es,ax
  677.      mov di,114+7*160
  678.      mov cx,5        ; idem que le processus précédent
  679. Bcl2:
  680.      lea si,Synchro1    ; on attend le processus 1
  681.      call p
  682.      mov ax,0
  683. Boucle2:
  684.     push cx
  685.     mov cx,9
  686.     call Affdec     ; on affiche le compteur
  687.     pop cx
  688.     inc ax
  689.     cmp ax,60000    ; jusqu'à 60000
  690.     jbe Boucle2
  691.     lea si,Synchro2    ; on signale au processus 1 qu'il peut bosser
  692.     call V
  693.     loop Bcl2
  694.  
  695.     lea si,sPrincipal
  696.     call v
  697.  
  698.     call Suicide
  699.  
  700. process2 ENDP
  701.  
  702. ; processus de compteur
  703.  
  704. process3 PROC
  705.     pusha
  706.      mov ax,@data
  707.      mov ds,ax
  708.      ASSUME ds:@data
  709.      mov ax,0B800h
  710.      mov es,ax
  711.      mov di,114+8*160
  712.      mov cx,10    ; dix fois
  713. Bcl3:
  714.      mov ax,0
  715. Boucle3:
  716.     push cx
  717.     mov cx,9
  718.     call Affdec ; on affiche le compteur
  719.     pop cx
  720.     inc ax
  721.     cmp ax,65000    ; jusqu'à 65000
  722.     jbe Boucle3
  723.     loop Bcl3
  724.  
  725.     lea si,sPrincipal
  726.     call v
  727.  
  728.     call Suicide
  729.  
  730. process3 ENDP
  731.  
  732. Process4 PROC
  733.      mov ax,@data
  734.      mov ds,ax
  735.      ASSUME ds:@data
  736.  
  737.      mov ax,0B800h
  738.      mov es,ax
  739.      mov di,114+9*160
  740.      mov cx,10
  741. Bcl4:
  742.      mov ax,0
  743. Boucle4:         ;
  744.     push cx         ;
  745.     mov cx,9         ;    Idem processus 3
  746.     call Affdec      ;
  747.     pop cx         ;
  748.     inc ax         ;
  749.     cmp ax,65534     ;
  750.     jbe Boucle4      ;
  751.     loop Bcl4
  752.  
  753.     lea si,sPrincipal
  754.     call v
  755.  
  756.     call Suicide
  757.  
  758. Process4 ENDP
  759.  
  760. Process5 PROC
  761.      mov ax,@data
  762.      mov ds,ax
  763.      ASSUME ds:@data
  764.  
  765.      mov ax,0B800h
  766.      mov es,ax
  767.      mov di,114+10*160
  768.      mov cx,10
  769. Bcl5:
  770.      mov ax,0
  771. Boucle5:
  772.     push cx
  773.     mov cx,9
  774.     call Affdec
  775.     pop cx
  776.     inc ax
  777.     cmp ax,65534
  778.     jbe Boucle5
  779.     loop Bcl5
  780.  
  781.     lea si,sPrincipal
  782.     call v
  783.  
  784.     call Suicide
  785.  
  786. Process5 ENDP
  787.  
  788. Process6 PROC
  789.      mov ax,@data
  790.      mov ds,ax
  791.      ASSUME ds:@data
  792.  
  793.      mov ax,0B800h
  794.      mov es,ax
  795.      mov di,114+11*160
  796.      mov cx,10
  797. Bcl6:
  798.      mov ax,0
  799. Boucle6:
  800.     push cx
  801.     mov cx,9
  802.     call Affdec
  803.     pop cx
  804.     inc ax
  805.     cmp ax,65534    ; même chose
  806.     jbe Boucle6
  807.     loop Bcl6
  808.  
  809.     lea si,sPrincipal
  810.     call v
  811.  
  812.     call Suicide
  813.  
  814. Process6 ENDP
  815.  
  816.  
  817.  
  818. ; Procedure d'affichage en base 10
  819. ;
  820. ; es:di = affichage
  821. ;
  822. ; cx : nombre de caractères à afficher
  823. ;
  824. ; ax = nombre à afficher
  825. ;
  826. AFFDEC PROC
  827.     pusha
  828.     add di,cx
  829.     add di,cx
  830.     sub di,2
  831. affich:
  832.     xor dx,dx
  833.     mov bx,10
  834.     div bx            ; on divise successivement par 10
  835.     add dl,30h        ; et on affiche les restes
  836.     mov es:[di],dl
  837.     sub di,2
  838.     dec cx
  839.     cmp ax,bx
  840.     jl finaff
  841.     jmp affich
  842. finaff:
  843.     add al,30h
  844.     mov es:[di],al        ; puis, on affiche le dernier résultat
  845.     sub di,2
  846.     dec cx
  847.     cmp cx,0
  848.     jz finaff3
  849. finaff2:
  850.     mov dl,30h        ; on affiche les 0 restants.
  851.     mov es:[di],dl
  852.     sub di,2
  853.     loop finaff2
  854. finaff3:
  855.     popa
  856.     RET
  857. AFFDEC ENDP
  858.  
  859. END
  860.