Ce code permet la communication série entre deux PCs. Lors de la reception d'un nouveau caractère sur la liaison série, l'interruption IRQ4 se déclenche, et une routine prend en charge son traitement. Une interruption est aussi générée dans le cas d'une erreur de réception.
Source / Exemple :
.386
donnees segment
;;;;;;;;;;;;;;; Port COM ;;;;;;;;;;;;;;;;;;;;
commprt equ 03F8h ; adresse de base du com1
THR equ commprt ; THR
DL_LSB equ commprt ; divisor latch LSB
DL_MSB equ commprt+1 ; divisor latch MSB
IER equ commprt+1 ; IT enable
IIR equ commprt+2 ; IT identification
FCR equ commprt+2 ; Fifo ctrl register
LCR equ commprt+3 ; ctrl ligne
MCR equ commprt+4 ; ctrl modem
LSR equ commprt+5 ; status ligne
MSR equ commprt+6 ; status modem
;;;;;;;;;;;;;;; Controlleur d'interruption ;;;;;;;;;
interr equ 21h
donnees ends
pile segment stack
dw 80 dup(?)
pile ends
code segment use16
assume cs:code,ds:donnees
prog proc far
;;;;;;;;;;;;; Sauvegarde des registres ;;;;;;;;;;;;;;;
push ds
push es
push ax
push si
push dx
;;;;;;;;;;;;; Initialisation des registres de segments ;;;;;;;;;;;;;;;;;;
mov ax,donnees
mov ds,ax
mov es,ax
;;;;;;;;;;;;; détournement de l'IRQ4 ;;;;;;;;;;;;;;;;;
cli ; désactive les interruptions
xor ax,ax
mov fs,ax ; fs = 0
mov dx,interr
in al,interr ; lecture du masque d'interruption
and al,0EFh ; démasque l'IRQ4
out dx,al ; écriture du masque
mov ax,cs ;
shl eax,16 ; eax = cs00h
mov ax,offset irq4 ; eax contient segment et offset de la nvlle routine d'interruption
mov fs:[0Ch*4],eax ; détourne l'irq4
;;;;;;;;;;;;; Initialisation du port COM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov al,80h ; DLAB=1
mov dx,LCR
out dx,al
mov al,0Ch ; 9600 bits/s
mov dx,DL_LSB
out dx,al
xor al,al
mov dx,DL_MSB
out dx,al
mov al,03h ; DLAB=0, 8 bits de données, 1 bit d'arrêt, aucune parité
mov dx,LCR
out dx,al
mov al,5 ; Active l'interruption donnee prete et l'interruption de changement du status de ligne
mov dx,IER
out dx,al
sti ; Autorise les interruptions
;;;;;;;;;;;;; programme principal ;;;;;;;;;;;;;;;;;;;;;;
start:
xor si,si
lea dx,moi
mov ah,09h
int 21h
loop1:
xor ax,ax ; lecture d'un caractère
int 16h
call send_char
cmp al,27 ; teste si touche=esc
jz fin ; sortir
mov dl,al ; afficher le caractère
mov ah,02h
int 21h
jnz loop1
send_quit:
call send_char
fin:
pop dx
pop si
pop ax
pop es
pop ds
mov ax,4C00h
int 21h
prog endp
irq4:
push ax
push dx
push ds
;;;;; Source de l'interruption ;;;;;;
mov dx,IIR
in al,dx
and al,6 ; conserver que bits 1 et 2
test al,6
jz erreur_ligne ; erreur ligne
; sinon donnée prête
mov dx,commprt ; lit un caractère du tampon de réception
in al,dx
mov dl,al
mov ah,02h ; l'affiche à l'écran
int 21h
jmp fin_irq4
erreur_ligne:
mov dx,LSR ; lecture de l'état de la ligne
in al,dx
test al,2 ; si bit 1 est = 1 => erreur overrun
jz overrun
test al,8
jz cadrage ; si bit 3 est = 1 => erreur cadrage (forme)
jmp fin_irq4
overrun:
lea dx,overrun_msg
mov ax,cs
mov ds,ax
mov ah,9
int 21h
jmp fin_irq4
cadrage:
lea dx,cadrage_msg
mov ax,cs
mov ds,ax
mov ah,9
int 21h
fin_irq4:
mov al,20h ; EOI
out 20h,al
pop ds
pop dx
pop ax
iret
overrun_msg db "erreur overrun$"
cadrage_msg db "erreur cadrage$"
;;;;;;;;;;;;; routine d'envoi d'un caracactère ;;;;;;;;;;;;;;;;
send_char proc near
push dx
push ax
mov dx,LSR
attend:
in al,dx
test al,20h
jz attend
pop ax
mov dx,commprt
out dx,al
pop dx
ret
send_char endp
code ends
end prog
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.