www.pudn.com > 8251-1.rar > 8251-1.ASM


;386以上微机适用 
;纯dos下才能使用 
;tasm4.1或以上编译 
;*********************; 
;*       8251        *; 
;*********************; 
 io_plx_device_id	equ 05406h	;TPC卡设备ID 
 io_plx_vendor_id	equ 010b5h	;TPC卡厂商ID 
 IO_PLX_SUB_ID		EQU 0905410B5H	;TPC卡子设备及厂商ID 
  DATA51 EQU 208H-200H             ;8251A DATA PORT 
  CTRL51 EQU 209H-200H             ;8251A COMMOND PORT 
  TIMER2 EQU 202H-200H             ;8253 COUNT2 
  TIMCTL EQU 203H-200H             ;8253 CTRL PORT 
  CLK00  EQU 250              ;8251A CLK 250KHZ 
  BPS00  EQU 1200             ;BPS=1200 
  FACTOR EQU 16               ;8251A BPS FACTOR=16 
data segment 
 io_base_address	db 4 DUP(0)	;TPC卡I/O基地址暂存空间 
 pcicardnotfind		db 0dh,0ah,'TPC pci card not find or address/interrupt error !!!',0dh,0ah,'$' 
 iobaseaddress		db 0dh,0ah,'TPC pci card I/O Base Address : ','$' 
 enter_return		db 0dh,0ah,'$' 
 MES  DB 'NOW YOU CAN PLAY A KEY ON THE CPU_KEYBORD',0AH,0DH 
      DB 'IT WILL DISPLAY ON THE TERMINAL_SCREEN' ,0AH,0DH 
      DB 'OR YOU CAN PRESS A KEY ON THE TERMINAL KEYBOARD',0AH,0DH 
      DB 'IT WILL DISPLAY ON THE CPU_SCREEN   ',0AH,0DH 
      DB 'PRESS ESC_KEY CAN FINISH COMMUNICATION',0AH,0DH,'$' 
data ends 
stacks segment 
 db 100 dup (?) 
stacks ends 
code segment 
        assume cs:code,ds:data,ss:stacks,es:data 
start: 
.386 
        cli 
        mov ax,data 
        mov ds,ax 
        mov es,ax 
        mov ax,stacks 
        mov ss,ax 
	call	findtpc		;查找TPC卡资源并显示 
 
        CALL SET_BPS		;初始化8253 
        CALL INIT51 
        MOV AX,DATA            ;DISPLAY MES 
        MOV DS,AX 
        LEA DX,MES 
        MOV AH,09 
        INT 21H 
FOREVER: 
	MOV  DX,word ptr io_base_address 
	add  dx,CTRL51 
	IN  AL,DX 
	TEST AL,02 
	JNZ RECEIVE 
	MOV AH,01              ;INPUT A CHAR FROM CPU_KEYBORD 
	INT 16H 
	JZ  FOREVER 
	MOV AH,0 
	INT 16H 
	CMP AL,1BH 
	JZ EXIT 
	MOV  DX,word ptr io_base_address 
	add  dx,DATA51 
	OUT DX,AL              ;CPU OUTPUT THE CHAR TO 8251A 
	mov dl,al 
	mov ah,02 
	int 21h 
	JMP FOREVER 
RECEIVE: 
	MOV  DX,word ptr io_base_address 
	add  dx,DATA51 
	IN  AL ,DX 
	CMP AL,1BH 
	JZ  EXIT 
	MOV DL,AL 
	inc dl 
	MOV AH,02 
	INT 21h 
	JMP FOREVER 
EXIT:   MOV AX,4C00H 
	INT 21H		;退出 
 
INIT51 PROC NEAR             ;INIT 8251A 
	MOV  DX,word ptr io_base_address 
	add  dx,CTRL51 
	XOR AX,AX 
	MOV CX,03 
LL:	CALL CHAROUT 
	LOOP LL 
	MOV AL,40H            ;RESET 8251A 
	CALL CHAROUT 
	mov al,4eh            ;DATA 8 BIT,STOP 1 BIT,FACTOR=16 
	call charout 
	MOV AL,27H            ;ENABLE INPUT AND OUTPUT 
	CALL CHAROUT 
	RET 
INIT51 ENDP 
 
CHAROUT PROC NEAR	;OUTPUT A BYTE 
	OUT DX,AL 
	PUSH CX 
	MOV CX,20h 
GG:	LOOP GG 
	POP CX 
	RET 
CHAROUT ENDP 
 
SET_BPS PROC NEAR           ;T/R CLOCK FROM TIMER2 
	MOV DX,0 
	MOV AX,CLK00 
	MOV BX,1000             ;COUNT2=CLK00*1000/FACTOR/BPS00 
	MUL BX 
	MOV BX,BPS00 
	DIV BX 
	MOV DX,00 
	MOV BX,FACTOR 
	DIV BX 
	MOV BX,AX 
	MOV  DX,word ptr io_base_address 
	add  dx,TIMCTL           ;TIMER2 IN MODE3 
	MOV AL,0B6H 
	OUT DX,AL 
	MOV  DX,word ptr io_base_address 
	add  dx,TIMER2 
	MOV AX,BX 
	OUT DX,AL 
	MOV AL,AH 
	OUT DX,AL 
	RET 
SET_BPS 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,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	dx,offset iobaseaddress		;显示i/o提示信息 
	mov	ah,09h 
	int	21h 
	mov	ax,word ptr io_base_address 
	call	dispword			;显示i/o基地址 
 
	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