;****************************************************************************; ;* I R Q *; ;*--------------------------------------------------------------------------*; ;* Fonction : Pratique du cours sur les IRQ. Ce programme initialise *; ;* les PICs, et modifie le gestionnaire du timer *; ;*--------------------------------------------------------------------------*; ;* Auteur : Aur‚lien *; ;* Groupe : A.P.C. ;* D‚velopp‚ le : 05.09.2000 *; ;* DerniŠre MAJ : 05.09.2000 *; ;*--------------------------------------------------------------------------*; ;* COMPILATEURS : TASM /ML /M2 /Q IRQ *; ;* TLINK /X /3 IRQ *; ;*--------------------------------------------------------------------------*; ;* Ce programme … au moins besoin d'un coprocesseur 80386 pour fonctionner *; ;*--------------------------------------------------------------------------*; ;* PROTEGE CONTRE LA NON-UTILISATION D'UN COPROCESSEUR 80386 OU SUPERIEUR *; ;****************************************************************************; .586 ;Initialisation du processeur 80586 _code segment use16 assume cs:_code, ds:_code, es:_code, ss:_stack ;== Messages d'erreur ======================================================== no386msg db "SYSTEM : A 80386 processor or greater is needed",13,10,'$' message db "A.P.C. Pratique du tutoriel sur les IRQs",13,10,13,10 db "Le gestionnaire du timer … ‚t‚ modifi‚e...",13,10 db "Appuyer sur une touche pour finir le programme",13,10,'$' ;== Variables ================================================================ IRQ_TIMER dw 0 ;Timer = IRQ0 SAVE_MASK_IRQ dw 0 ;Sauvegarde du masque d'IRQ ;== Gestionnaire d'interruption du Timer ===================================== ligne db 0 ;Ligne d'affichage du caractŠre colonne db 79 ;Colonne d'affichage du caractŠre caractere db 0 ;CaractŠre affich‚ en haut … gauche de l'‚cran lig db 0 ;Ligne d'affichage du caractŠre nø2 col db 0 ;Colonne d'affichage du caractŠre nø2 number db 0 ;nunm‚ro du second caractŠre character db '|','/','-','\' ancint equ this dword ;Ancien vecteur d'interruption ofsancint dw (?) ;Adresse d'offset du vecteur d'interruption segancint dw (?) ;Adresse de segment vecteur d'interr. new_timer: pushad ;Sauvegarde imp‚rative de tout les registres push ds ;Puis des registres de segment push es push fs push gs push ss push cs ;Initialise les registres de segment push cs pop ds ;DS pop es ;et ES ;Sauvegarde de la position du curseur mov ah, 3 ;Lecture de la position du curseur xor bx, bx ;Page ‚cran 0 int 10h push dx ;Sauvegarde de la position ;Affichage du premier caractŠre mov ah, 2 ;Positionnement du curseur xor bh, bh ;page ‚cran 0 mov dh, ligne ;ligne mov dl, colonne ;colonne int 10h mov ah, 9 ;Affichage d'un caractŠre mov bh, 0 ;Page ‚cran 0 mov cx, 1 ;On affiche seulement une fois le caractŠre mov al, caractere ;num‚ro du caractŠre mov bl, 1eh ;Attribut de couleur (fond bleu caractŠre jaune) int 10h ;Affichage du second caractŠre mov ah, 2 ;Positionnement du curseur xor bh, bh ;page ‚cran 0 mov dh, lig ;ligne mov dl, col ;colonne int 10h xor bx, bx mov bl, number ;Num‚ro du caractŠre mov al, byte ptr cs:[bx+character] ;Recherche du caractŠre mov ah, 9 ;Affichage d'un caractŠre mov bh, 0 ;Page ‚cran 0 mov cx, 1 ;On affiche seulement une fois le caractŠre mov bl, 1ah ;Attribut de couleur (fond bleu caractŠre vert pomme) int 10h inc number ;Incr‚mente le curseur cmp number, 4 ;Test si maximum d‚pass‚ jne end_gest mov number, 0 ;RAZ du nombre ;Repositionnement du curseur end_gest: mov ah, 2 ;Positionnement du curseur pop dx ;A son endroit d'origine int 10h inc caractere ;incr‚mente le num‚ro ASCII du caractŠre ;Envoie du code EOI ;Comme nous appelons l'ancien gestionnaire, c'est lui qui enverra ce code ;donc je vous indique les lignes … mettre, en commentaire. ; mov al, 20h ;Code EOI ; out 20h, al ;Envoie sur le maŒtre uniquement ; ;Car c'est l'IRQ du maŒtre et non de l'esclave pop ss ;Recharge les anciennes valeur des registres pop gs ;de segment pop fs pop es pop ds popad ;et g‚n‚raux jmp cs:[ancint] ;Saute … l'ancienne interrution ;== Programme principal ====================================================== start: ;V‚rification du processeur si > 80386 xor ax, ax pushf xor ah, ah push ax popf pushf pop ax and ah, 0f0h cmp ah, 0f0h je no386 jmp debut no386: mov dx, offset no386msg err16: mov ax, _code mov ds, ax mov es, ax mov ah, 09h int 21h mov ax, 4c00h int 21h ;** D‚but du programme principal ********************************************* debut: mov ax, _code mov ds, ax mov es, ax ;Initialisation des deux PICs ;ICW1 mov al, 00010001b ;mode attaque, PIC en cascade et envoie de ICW4 out 20h, al ;Envoie au le maŒtre out 0a0h, al ;Puis … l'esclave ;ICW2 mov al, 8h ;IRQ0 = INT8 -> IRQ7 = INT0FH out 21h, al ;Envoir au le maŒtre mov al, 70h ;IRQ8 = INT70H -> IRQ15 = INT77H out 0a1h, al ;Envoie … l'esclave ;ICW3 mov al, 00000100b ;IRQ2 est li‚ … l'eclave out 21h, al ;Envoie au maŒtre mov al, 2 ;esclave reli‚ … l'IRQ2 out 0a1h, al ;Envoie … l'eclave ;ICW4 mov al, 00000001b ;Interruption termin‚e manuellement, fonctionne avec un Intel 80x86 out 21h, al ;Envoie sur le maŒtre out 0a1h, al ;Envoie … l'esclave ;L'initialisation des PICs est termin‚, nous allons bien param‚trer l'IRQ0 ;pour ˆtre s–re qu'elle soit activ‚, ... ;OCW1 in al, 0a1h ;Lecture du masque d'autorisation des interruptions mov ah, al ;Sur l'esclave in al, 21h ;puis sur le maŒtre mov SAVE_MASK_IRQ, ax ;Sauvegarde du masque pour le restituer … la fin mov bx, IRQ_TIMER ;IRQ du timer not bx ;NON logique and ax, bx ;Annulation du bit du timer grƒce au ET logique out 21h, al ;Envoie le masque au maŒtre mov al, ah out 0a1h, al ;puis … l'esclave ;L'IRQ du timer est donc bine activ‚. Nous pouvons maintenant installer ;le nouveau gestionnaire du timer. ;Pour ‚viter tout plantage du systŠme, l'ancien gestionnaire est appel‚ mov ax,3508h ;Lire le contenu du vecteur d'interruption du timer int 21h mov segancint,es ;Ranger adresse de segment et d'offset mov ofsancint,bx ;du vecteur d'interruption push cs ;R‚initialisation push cs ;des registres de segment pop es pop ds mov dx,offset new_timer ;Adresse de la nouvelle routine d'interr. mov ax,2508h ;Modifier l'adresse de l'interruption timer int 21h mov ah, 9 ;Afficher un message mov dx, offset message ;Adresse du message int 21h mov ah, 0 ;attend la frappe d'une touche int 16h ;Recharger l'ancien vecteur d'interruption du timer, puis fini le programme mov dx,es:ofsancint ;Adresse d'offset de l'interruption timer mov ax,es:segancint ;adresse de segment de l'interruption timer mov ds,ax ;Dans DS mov ax,2508h ;Rechargement du contenu de l'ancienne adresse de l'interruption int 21h ;Puis restore les masques d'IRQ mov ax, SAVE_MASK_IRQ ;Masques d'IRQ out 21h, al ;Envoie le masque au maŒtre mov al, ah out 0a1h, al ;Puis … l'esclave fin: mov ax, 4c00h int 21h _code ends _stack segment stack use16 db 200h dup(?) _stack ends EndPrg: end start