www.pudn.com > INT.rar > INT.ASM


;386以上微机适用 
;纯dos下才能使用 
;tasm4.1或以上编译 
;*********************; 
;*       中断        *; 
;*********************; 
 io_plx_device_id	equ 05406h	;TPC卡设备ID 
 io_plx_vendor_id	equ 010b5h	;TPC卡厂商ID 
 IO_PLX_SUB_ID		EQU 0905410B5H	;TPC卡子设备及厂商ID 
 TIM_CTL		EQU 203H-200H	;8253端口地址 
 TIMER0			EQU 200H-200H 
 TIMER1			EQU 201H-200H 
 MODE03			EQU 36H		;8253端口数据 
 MODE12			EQU 74H 
data segment 
 csreg	dw	? 
 ipreg	dw	?	;旧中断向量保存空间 
 irq_times	dw	00h	;中断计数 
 msg1    db      0dh,0ah,'TPC pci card Interrupt',0dh,0ah,'$' 
 msg2    db      0dh,0ah,'Press any key to exit!',0dh,0ah,'$' 
 msg3    db      0dh,0ah,'Press DMC or wait to interrupt 10 times and exit!',0dh,0ah,'$' 
 io_9054base_address	db 4 DUP(0)	;TPC卡PCI接口芯片I/O基地址暂存空间 
 io_base_address	db 4 DUP(0)	;TPC卡I/O基地址暂存空间 
 interrupt_line		db 2 DUP(0)	;TPC卡中断号暂存空间 
 pcicardnotfind		db 0dh,0ah,'TPC pci card not find or address/interrupt error !!!',0dh,0ah,'$' 
 io9054baseaddress	db 0dh,0ah,'TPC pci card 9054 Chip I/O Base Address : ','$' 
 iobaseaddress		db 0dh,0ah,'TPC pci card I/O Base Address : ','$' 
 intnumber		db 0dh,0ah,'TPC pci card Interrupt Line : ','$' 
 enter_return		db 0dh,0ah,'$' 
 MESS	 DB	   '8253A TIMER0 IN MODE3! COUNT=0200H',0AH,0DH 
         DB        '8253A TIMER1 IN MODE2! COUNT=0aH',0AH,0DH,'$' 
 irq_vect		db 08h,09h,0ah,0bh,0ch,0dh,0eh,0fh,70h,71h,72h,73h,74h,75h,76h,77h 
			;新的中断向量,中断0-7的向量为:08h-0fh,中断8-15的向量为:70h-77h 
 irq_mask_0_7_table	db 011111110b,011111101b,011111011b,011110111b 
			db 011101111b,011011111b,010111111b,001111111b 
			db 011111011b,011111011b,011111011b,011111011b 
			db 011111011b,011111011b,011111011b,011111011b 
			;新的中断掩码,中断0-7时从低至高相应位为零,中断8-15时第2位为零 
 irq_mask_8_15_table	db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh 
			db 011111110b,011111101b,011111011b,011110111b 
			db 011101111b,011011111b,010111111b,001111111b 
			;新的中断掩码,中断0-7时全一,中断8-15时从低至高相应位为零 
data ends 
stacks segment 
 db 100 dup (?) 
stacks ends 
code segment 
        assume cs:code,ds:data,ss:stacks,es:data 
start: 
;Enable Local Interrupt Input 
.386 
        cli 
        mov ax,data 
        mov ds,ax 
        mov es,ax 
        mov ax,stacks 
        mov ss,ax 
	call	findtpc		;查找TPC卡资源并显示 
 
	MOV  DX,word ptr io_base_address	;初始化8253 
	add  dx,TIM_CTL 
	MOV  AL,MODE03 
	OUT  DX,AL 
	MOV  DX,word ptr io_base_address 
	add  dx,TIMER0 
	MOV  AL,00h 
	OUT  DX,AL 
	MOV  AL,02H 
	OUT  DX,AL 
	MOV  DX,word ptr io_base_address 
	add  dx,TIM_CTL 
	MOV  AL,MODE12 
	OUT  DX,AL 
	MOV  DX,word ptr io_base_address 
	add  dx,TIMER1 
	MOV  AL,0aH 
	OUT  DX,AL 
	MOV  AL,00 
	OUT  DX,AL 
	MOV  DX,OFFSET MESS 
	MOV  AH,09 
	INT  21H 
 
	mov  dx,word ptr io_9054base_address 
	add  dx,68h  ;设置 tpc 卡中9054芯片io口,使能中断 
        in ax,dx 
        or ax,0900h 
        out dx,ax 
 
        mov bx,word ptr interrupt_line	;保存原中断向量 
	mov al,byte ptr [irq_vect+bx] 
	mov ah,35h 
        int 21h 
	mov ax,es 
	mov csreg,ax 
	mov ipreg,bx 
 
        mov bx,word ptr interrupt_line	;设置新中断向量 
        mov al,byte ptr [irq_vect+bx] 
        mov cx,cs 
        mov ds,cx 
	mov dx,offset int_proc 
	mov ah,25h 
        int 21h 
 
	mov ax,data 
	mov ds,ax 
	mov es,ax 
        in      al, 21h         ;设置中断掩码 
        mov bx,word ptr interrupt_line 
	mov ah,byte ptr [irq_mask_0_7_table+bx] 
	and	al,ah 
        out     21h, al 
        in      al, 0a1h 
        mov bx,word ptr interrupt_line 
	mov ah,byte ptr [irq_mask_8_15_table+bx] 
	and	al,ah 
        out     0a1h, al 
 
        mov dx,offset msg2 
	mov ah,09h 
	int 21h 
        mov dx,offset msg3 
	mov ah,09h 
	int 21h 
	mov irq_times,0ah 
	sti                ;开中断 
 
loop1: 
        cmp irq_times,0		;等待中断并判断中断10次后退出 
        jz exit 
	mov ah,1 
	int 16h 
        jnz exit		;按任意键退出 
        jmp loop1 
 
exit:   cli 
        mov bx,word ptr interrupt_line		;恢复中断掩码 
	mov ah,byte ptr [irq_mask_0_7_table+bx] 
	not ah 
	in	al, 21h 
	or	al, ah 
	out	21h, al 
        mov bx,word ptr interrupt_line 
	mov ah,byte ptr [irq_mask_8_15_table+bx] 
	not ah 
	in	al, 0a1h 
	or	al, ah 
	out	0a1h, al 
 
        mov bx,word ptr interrupt_line		;恢复原中断向量 
	mov al,byte ptr [irq_vect+bx] 
        mov dx,ipreg 
	mov cx,csreg 
	mov ds,cx 
	mov ah,25h 
        int 21h 
 
	mov ax,data	;设置 tpc 卡中9054芯片io口,关闭中断 
        mov ds,ax 
	mov dx,word ptr io_9054base_address 
	add dx,68h 
	in  ax,dx 
        and ax,0f7ffh 
	out dx,ax 
 
	mov ax,4c00h 
	int 21h		;退出 
 
int_proc proc far 
        cli 
        push ax 
        push dx 
        push ds 
        dec irq_times 
        mov ax,data             ;Interrupt to do 
        mov ds,ax 
	mov dx,offset msg1 
	mov ah,09h 
	int 21h 
 
        mov al,20h              ;Send EOI 
        out 0a0h,al 
        out 20h,al 
        mov     cx,0ffffh 
loopx: 
        nop 
        loop    loopx                      ;延时 
        pop ds 
        pop dx 
        pop ax 
        sti 
        iret 
int_proc endp 
 
findtpc proc near		;查找TPC卡资源并显示 
	pushad 
	pushfd 
	MOV	AX,0B101H 
	INT	1AH 
	JC	findtpc_notfind		;检查PCI BIOS是否存在 
 
	MOV	AX,0B102H 
	MOV	CX,io_plx_device_id 
	MOV	DX,io_plx_vendor_id 
	MOV	SI,0 
	INT	1AH 
	JC	findtpc_notfind		;检查TPC卡是否安装,设备号、厂商号 
 
	MOV	AX,0B10AH 
	MOV	DI,02CH 
	INT	1AH 
	JC	findtpc_notfind 
	CMP	ECX,IO_PLX_SUB_ID 
	JNZ	findtpc_notfind		;检查TPC卡是否安装,子设备号、厂商号 
 
	MOV	AX,0B10AH 
	MOV	DI,14H 
	INT	1AH 
	JC	findtpc_notfind		;读TPC卡9054芯片I/O基址信息 
	mov	dword ptr io_9054base_address,ecx 
	and	ecx,1 
	jz	findtpc_notfind		;检查是否为i/o基址信息 
        mov	ecx,dword ptr io_9054base_address 
	and	ecx,0fffffffeh 
        mov	dword ptr io_9054base_address,ecx  ;去除i/o指示位并保存 
 
	MOV	AX,0B10AH 
	MOV	DI,18H 
	INT	1AH 
	JC	findtpc_notfind		;读TPC卡I/O基址信息 
	mov	dword ptr io_base_address,ecx 
	and	ecx,1 
	jz	findtpc_notfind		;检查是否为i/o基址信息 
	mov	ecx,dword ptr io_base_address 
	and	ecx,0fffffffeh 
	mov	dword ptr io_base_address,ecx	;去除i/o指示位并保存 
 
	MOV	AX,0B10AH 
	MOV	DI,3CH 
	INT	1AH 
	JC	findtpc_notfind		;读TPC卡中断信息 
	and	cx,0ffh 
	mov	word ptr interrupt_line,cx	;去除interrupt其它指示位并保存 
 
        mov	dx,offset io9054baseaddress	;显示i/o提示信息 
	mov	ah,09h 
	int	21h 
        mov	ax,word ptr io_9054base_address 
	call	dispword			;显示i/o基地址 
 
	mov	dx,offset iobaseaddress		;显示i/o提示信息 
	mov	ah,09h 
	int	21h 
	mov	ax,word ptr io_base_address 
	call	dispword			;显示i/o基地址 
 
	mov	dx,offset intnumber		;显示interrupt提示信息 
	mov	ah,09h 
	int	21h 
	mov	ax,word ptr interrupt_line 
	call	dispword			;显示中断号 
 
	mov	dx,offset enter_return		;加回车符,换行符 
	mov	ah,09h 
	int	21h 
	popfd 
	popad 
	ret 
findtpc_notfind: 
	mov dx,offset pcicardnotfind		;显示未找到tpc卡提示信息 
	mov ah,09h 
	int 21h 
	mov ax,4c00h 
	int 21h		;退出 
findtpc endp 
 
dispword proc near		;显示子程序 
	push dx 
	push cx 
	push bx 
	mov cx,4 
	mov bx,16 
dispword_loop1: 
	push ax 
	push cx 
	sub bx,4 
	mov cx,bx 
	shr ax,cl 
	and al,0fh	;首先取低四位 
	mov dl,al 
	cmp dl,9	;判断是否<=9 
	jle dispword_num		;若是则为'0'-'9',ASCII码加30H 
	add dl,7	;否则为'A'-'F',ASCII码加37H 
dispword_num: 
	add dl,30h 
	mov ah,02h	;显示 
	int 21h 
	pop cx 
	pop ax 
	loop dispword_loop1 
	pop bx 
	pop cx 
	pop dx 
	ret		;子程序返回 
dispword endp 
code ends 
end start