www.pudn.com > LED1.rar > LED.ASM


;386以上微机适用 
;纯dos下才能使用 
;tasm4.1或以上编译 
;*********************; 
;*        LED        *; 
;*********************; 
 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 
 INTA00			EQU 20H 
 INTA01			EQU 21H 
 PORTSEG		EQU 211H-200H	;数码管端口地址 
 PORTBIT		EQU 210H-200H 
data segment 
 csreg	dw	? 
 ipreg	dw	?	;旧中断向量保存空间 
 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时从低至高相应位为零 
 MIN1     DB        0 
 MIN2     DB        0 
 GAP1     DB        10 
 GAP2     DB        10 
 SEC1     DB        0 
 SEC2     DB        0 
 INTMASK  DB        ? 
 COUNT    DB        0 
 LED      DB        3FH,06,5BH,4FH,66H,6DH,7DH,07,7FH,6FH,40H 
 MES      DB        'DISPLAY THE LEDS,PRESS ANY KEY TO EXIT!' 
	  DB        0AH,0DH,'$' 
data ends 
stacks segment 
 db 100 dup (?) 
STA      DW        512 DUP (?) 
TOP      EQU       LENGTH STA 
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,OFFSET MES	;显示提示 
	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 
 
	sti                ;开中断 
 
loop1: 
	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 CX 
        push dx 
	PUSH DI 
        push ds 
	 MOV       AX,DATA 
	 MOV       DS,AX 
	 MOV       DI,OFFSET MIN1 
	 MOV       CL,01 
DIS1:    MOV       AL,[DI] 
	 MOV       BX,OFFSET LED 
	 XLAT 
        MOV  DX,word ptr io_base_address 
        add  dx,PORTSEG 
        OUT       DX,AL 
        MOV       AL,CL 
        MOV  DX,word ptr io_base_address 
        add  dx,PORTBIT 
	 OUT       DX,AL 
	 PUSH      CX 
         MOV       CX,8000H     ;显示时间延迟 
DELAY:   LOOP      DELAY 
	 POP       CX 
	 CMP       CL,20H   
	 JZ        CHG 
	 INC       DI 
	 SHL       CL,1     
	 MOV       AL,00 
	 OUT       DX,AL 
	 JMP       DIS1 
CHG:     INC       COUNT        
	 CMP       COUNT,50 
	 JL        QUIT 
	 MOV       COUNT,0 
	 INC       SEC2 
	 CMP       SEC2,10 
	 JL        QUIT 
	 MOV       SEC2,0 
	 INC       SEC1 
	 CMP       SEC1,6 
	 JL        QUIT 
	 MOV       SEC1,0 
	 INC       MIN2 
	 CMP       MIN2,10 
	 JL        QUIT 
	 MOV       MIN2,0 
	 INC       MIN1 
	 CMP       MIN1,6 
	 JL        QUIT 
	 MOV       MIN1,0 
QUIT: 
        MOV  DX,word ptr io_base_address 
        add  dx,PORTBIT 
        MOV       AL,00 
        OUT       DX,AL 
 
        mov al,20h              ;Send EOI 
        out 0a0h,al 
        out 20h,al 
        mov     cx,0ffffh 
loopx: 
        nop 
        loop    loopx                      ;延时 
        pop ds 
	POP DI 
        pop dx 
	POP CX 
        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