📄 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -