⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s7026.cpp

📁 DOS下使用PCI扩展串口的程序希望对大家有用
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#else
   asm push eax
   asm in eax,dx ;
   asm mov [bx],eax ;
   asm pop eax
#endif
   return value ;
}
#endif /* __WATCOMC__ */

//----------------------------------------------------------------------

#if defined(__WATCOMC__) && defined(__386__)
extern void outpd(int portnum, DWORD value) ;
#pragma aux outpd = \
   "out dx,eax" \
   parm [edx][eax] \
   modify exact [] ;

#else
static void outpd(int portnum, DWORD val)
{
   static DWORD value = 0 ;

   value = val ;
   asm mov dx,portnum ;
   asm lea bx,value ;
#if defined(__BORLANDC__)
   __emit__(0x66,0x50,                  // push EAX
			0x66,0x8B,0x07,             // mov EAX,[BX]
			0x66,0xEF,                  // out DX,EAX
			0x66,0x58) ;                // pop EAX
#else
   asm push eax
   asm mov eax,[bx] ;
   asm out dx,eax ;
   asm pop eax
#endif
   return ;
}
#endif /* __WATCOMC__ */

//----------------------------------------------------------------------

#if defined(__WATCOMC__)
extern void outp(short portnumber, BYTE value) ;
#pragma aux outp = \
   "out dx,al" \
   parm [dx][al] \
   modify exact [] ;

extern BYTE inp(short portnumber) ;
#pragma aux inp = \
   "in al,dx" \
  parm [dx] \
  value [al] \
  modify exact [al] ;
#endif /* __WATCOMC__ */


static int bypass_BIOS = FALSE ;
static int cfg_mech = 1 ;               // PCI access mechanism: 1 or 2
static int read_DWORD_register(int bus, int device, int func, int reg,
			       WORD *lo, WORD *hi)
{
   if (bypass_BIOS)
   {
	  DWORD value ;
	  if (cfg_mech == 1)
	  {
		 DWORD addr = 0x80000000L | (((DWORD)(bus & 0xFF)) << 16) |
					  ((((unsigned)device) & 0x1F) << 11) |
					  ((((unsigned)func) & 0x07) << 8) | (reg & 0xFC) ;
		 DWORD orig = inp(0xCF8) ;      // get current state
		 outpd(0xCF8,addr) ;            // set up addressing to config data
		 value = inpd(0xCFC) ;          // get requested DWORD of config data
		 outpd(0xCF8,orig) ;            // restore configuration control
	  }
	  else // cfg_mech == 2
	  {
		 if (device > 0x0F)             // mech#2 only supports 16 devices
		 {                           //   per bus
			*lo = 0xFFFF ;
			*hi = 0xFFFF ;
			return FALSE ;
		 }
		 BYTE oldenable = inp(0xCF8) ;  // store current state of config space
		 BYTE oldbus = inp(0xCFA) ;
		 outp(0xCFA,bus) ;
		 outp(0xCF8,0x80) ;             // enable configuration space
		 WORD addr = 0xC000 | ((device & 0x0F) << 8) | (reg & 0xFF) ;
		 value = inpd(addr) ;
		 outp(0xCFA,oldbus) ;           // restore configuration space
		 outp(0xCF8,oldenable) ;
	  }
	  *hi = (WORD)(value >> 16) ;
	  *lo = (WORD)(value & 0xFFFF) ;
	  return TRUE ;
   }
   else // use BIOS
   {
	  union REGS regs, outregs ;
	  regs.h.bh = bus ;
	  regs.h.bl = (device<<3) | (func & 0x07) ;
#if defined(__WATCOMC__) && defined(__386__)
	  regs.w.ax = 0xB109 ;
	  regs.w.di = reg ;
	  int386(0x1A,&regs,&outregs) ;
	  if (outregs.x.cflag != 0)
		 return FALSE ;
	  *lo = outregs.w.cx ;
	  regs.w.di += 2 ;
	  int386(0x1A,&regs,&outregs) ;
	  if (outregs.x.cflag != 0)
		 return FALSE ;
	  *hi = outregs.w.cx ;
#else
	  regs.x.ax = 0xB109 ;
	  regs.x.di = reg ;
	  int86(0x1A,&regs,&outregs) ;
	  if (outregs.x.cflag != 0)
		 return FALSE ;
	  *lo = outregs.x.cx ;
	  regs.x.di += 2 ;
	  int86(0x1A,&regs,&outregs) ;

	  if (outregs.x.cflag != 0)
		 return FALSE ;
	  *hi = outregs.x.cx ;
#endif /* __WATCOMC__ && __386__ */
   }
   return TRUE ;
}


extern PCIcfg *read_PCI_config(int bus, int device, int func)
{
  static PCIcfg cfg ;

  for (int i = 0 ; i < sizeof(cfg)/sizeof(DWORD) ; i++)
  {
	WORD hi, lo ;
	if (!read_DWORD_register(bus,device,func,i*sizeof(DWORD),&lo,&hi))
	   return 0 ;
	((WORD*)&cfg)[2*i] = lo ;
	((WORD*)&cfg)[2*i+1] = hi ;
  }
  return &cfg ;

}

/******************************Query com mode*********************************/
void   querytest(unsigned int gstep, unsigned int gstepn)
{
	int   i,n;
	char  ch;
	Port1=BaseAdr+portadr[gstep];
	Port2=BaseAdr+portadr[gstepn];

	traport=Port1;
	recport=Port2;
	for (i=0,n=0; n<125; n++)
	{
		 while ((inportb(traport+LSR) & 0x20)==0x00);
			   outportb(traport, n);
		 while ((inportb(recport+LSR) & 0x01)==0x00);
			   ch=inportb(recport);
		 if (ch!=n)
		 {
			 i++;
			 printf("%c", n);
		 }
	}
	if (i==0)
	   printf("PORT%d ->PORT%d Query COM OK\n", gstep+1,gstepn+1);
	else
	   {printf("error number %d\n",i); i=0;}

	traport=Port2;
	recport=Port1;
	for (i=0,n=0; n<125; n++)
	{
		 while ((inportb(traport+LSR) & 0x20)==0x00);
		   outportb(traport, n);
		 while ((inportb(recport+LSR) & 0x01)==0x00);
		   ch=inportb(recport);
		 if (ch!=n)
		 {
			 i++;
			 printf("%c", n);
		 }
	}
	 if (i==0)
		printf("PORT%d ->PORT%d Query COM OK\n", gstepn=1,gstep+1);
	 else
		{printf("error number %d\n", i);i=0;}

}

/***  Interrupt receive  ***/
void Inter_txrx(int intnum)
{
	 disable();
	 oldvect=getvect(vectadr[intnum]);
	 if (intnum < 8)
		outportb(mainMIR,inportb(mainMIR) & ~disinter[intnum]);
	 else
	 {
		 outportb(seconMIR,inportb(seconMIR) & ~disinter[intnum-8]);
		 outportb(mainMIR,inportb(mainMIR) & 0x0Fb);
	 }
	 setvect(vectadr[intnum],comtxrx);
	 enable();
}

/***  Interrupt subprogramm  ***/
unsigned  int   i,j,ide[PORTSUM];
unsigned  char IIReg=0;
unsigned int port,h;
unsigned char tempbuf[rb_size];
void interrupt    comtxrx(...)
{

   for (h=0; h < PORTSUM; h++)
   {
		IIReg=inportb(BaseAdr+portadr[h]+ISR) & 0x0f;
		if (IIReg != 1)
		   {port=BaseAdr+portadr[h];break;}/*==1 no pending interrupt*/
   }
   for (; ;)
   {
	 if (IIReg == 0x06)
		IIReg=0x04;/**/
	 if (IIReg == 0x04)
	 {
		 if (modevar == 6)
		 {
			  for (head1=reclevel; head1 != tail1; head1++)   //TTL setis ;
			  {
				   re_rec=1;
				   BBuffer[h][ide[h]++]=inportb(port);
				   if ((inportb(port+LSR) & 0x01) != 1)break;
			  }
		 }
		 else if (modevar == 4)
		 {
			  for (head1=rb_size-rtl650; head1 != tail1; head1++)
			  {
				  re_rec=1;
				  BBuffer[h][ide[h]++]=inportb(port);
				  if ((inportb(port+LSR) & 0x01) != 1)break;
			  }
		 }
		 else if ((inportb(port+LSR) & 0x01) == 1)
		 {
			  re_rec=1;
			  BBuffer[h][ide[h]++]=inportb(port);
		 }

		 i=ide[h];
	 }
	 if (IIReg == 0x02)
	 {
		 if (modevar == 6)
		 {
			 for (head1=tralevel; head1 != tail1; head1++)   //TTL setis ;
			 {
				   outportb(port, txbuf1[head1]);
			 }
			 outportb(port+IER, 0x01);
		 }
		 else if (modevar == 4)
		 {
			  for (head1=rb_size-titl650; head1 != tail1; head1++)
			  {
				  outportb(port, txbuf1[head1]);
			  }
			  outportb(port+IER, 0x01);
		 }
		 else if (head1 != tail1)
		 {
			 head1++;
			 outportb(port, txbuf1[head1]);
			 if (head1 >= rb_size)
				head1=0;
			 outportb(port+IER, 0x01);
		 }
	 }

	 for (h=0; h < PORTSUM; h++)
	 {
		IIReg=inportb(BaseAdr+portadr[h]+ISR) & 0x0f;
		if (IIReg != 1)
		{
			port=BaseAdr+portadr[h];
			break;/*==1 no pending interrupt*/
		}
	 }

	  if (h == PORTSUM)
		 break;
	 }

	 outportb(0x20,0x20);
	 outportb(0xa0,0x20);
}

/****************************************************************/

	FILE * com1_fp;
	FILE * com2_fp;
/*******************************Interrupt com*******************************/
int Intertxrx( )
{
	long timesec;
	int   k,l,m;
	unsigned  int x,y;
	unsigned  int   errno;
	unsigned  int   recright;
	unsigned  int   cyccount;
	unsigned  char  slength,stsleng;
	unsigned  char  Rtemp[rb_size+1];
	unsigned  char  Stemp[rb_size+1];
	unsigned  char  intok[PORTSUM];

	unsigned  char  com1_writebufferid;//write which buffer
	unsigned  char  com1_writefileid; //=1;write file

	unsigned  char  com2_writebufferid;//write which buffer
	unsigned  char  com2_writefileid; //=1;write file

	com1_writefileid=1; //initial variable
	com1_writebufferid=1;

	com2_writefileid=1; //initial variable
	com2_writebufferid=1;
	com1_fp=fopen("\\com1xx.dat","wb");
	fclose(com1_fp);
	com2_fp=fopen("\\com2xx.dat","wb");
	fclose(com2_fp);

	transf=0;receivf=0;
	tralevel=rb_size-titl950;
	reclevel=rb_size-rtl950;
	ErrorCode=0;
	ErrDetected=0;
	stsleng=0;
	//stsleng=strlen(strings);
	if (stsleng > 127)
	{
		printf("the strings length from you input: %d\n",stsleng);
		fprintf(stderr,"expect    it  less  than 128");
		stsleng=127;
	}
	if (stsleng < 1)
	{
		for (head1=0,tail1=0; tail1<rb_size; tail1++)
			txbuf1[tail1]=(unsigned char)(tail1+33);
		for (head2=0,tail2=0; tail2<rb_size; tail2++)
			txbuf2[tail2]=(unsigned char)(tail2+35);
	}
	else
	{
		tail1=rb_size;head1=rb_size; k=stsleng;
		do
		{
			txbuf1[--head1]=strings[--k];
			if (k == 0)k=stsleng;
		}while (head1);
		tail2=rb_size;head2=rb_size; k=stsleng;
		do
		{
			txbuf2[--head2]=strings[--k];
			if (k == 0)k=stsleng;
		}while (head2);
	}


	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	for (i=0; i < PORTSUM; i++)
	{
		BBuffer[i][0]=0xff;
		ide[i]=0;
		outportb(BaseAdr+portadr[i]+LCR, inportb(BaseAdr+portadr[i]+LCR) & 0x7f);
		while ((inportb(BaseAdr+portadr[i]+LSR) & 0x01) == 0x01)
			 inportb(BaseAdr+portadr[i]);
		outportb(BaseAdr+portadr[i]+IER, 0x00);
	}
	Inter_txrx(intvet);

	if (portsend==1)
	{
		modevar=5;// adopted to other serial device port
		outportb(BaseAdr+portadr[gstep]+LCR,0xbf);
		outportb(BaseAdr+portadr[gstep]+FCR,0x2f|fcr76rtl);
		outportb(BaseAdr+portadr[gstep]+LCR,lcr10dl|lcr2nos|lcr53pt);
	}

	if ((gstep < PORTSUM) && (gstepn < PORTSUM))      //select two port communite
	{
		  outportb(BaseAdr+portadr[gstepn]+IER, 0x01);
		  if (modevar == 6)
		  {
			  for (head2=tralevel; head2 != rb_size; head2++)//trigger empty trans
			  {
				   outportb(BaseAdr+portadr[gstep], txbuf1[head2]);
			  }
		  }
		  else if (modevar == 4)
		  {
			  for (head2=(rb_size-titl650); head2 != rb_size; head2++)//trigger empty trans
			  {
				   outportb(BaseAdr+portadr[gstep], txbuf1[head2]);
			  }
		  }
		  else
		  {
			   outport(BaseAdr+portadr[gstep],txbuf1[1]);
			   head1=0;
		  }
		  if (display==1)
		  {
			  printf("PORT%d Interrupt received char number and last char:",gstepn+1);
			  x=wherex();
			  y=wherey();
		  }

		  timesec=time(NULL);
		  for (i=0 ; i < SIZEb-rb_size;)
		  {
			   receivf=0;
			   transf=0;
			   outportb(BaseAdr+portadr[gstep]+IER, 0x02);
			   //enable transmit and  receive interrupt
			   if (display==1)
			   {
				   if (re_rec==1)
				   {
					   gotoxy(x,y);
					   printf("%d %c",i,BBuffer[gstepn][i-1]);
					   re_rec=0;
				   }
			   }
			   if ((time(NULL)-timesec) > 20)
			   {
					fprintf(stderr,"\ncheck physical connection,confirmed right and try again\n");
					printf("if confirmed, what wrong with the two ports \n");
					exit(0);
			   }

			   if ((1==transf)&&(0==receivf))
			   {
				   printf("PORT%d couldn't receive,check physical connection\n",gstepn+1);
				   transf=0;
				   break;
			   }
			   if ((bioskey(1)!=0))//press any key to break
			   {
				   bioskey(0);
				   break;
			   }
				//delay(20);
		  }
		  if (display==1)
		      printf("\n");
		  delay(8);
		  //reset and set in 485 mode
		  IndecontrolReg(BaseAdr,portadr[gstep],0x0c,0x00);
		  UartsRegsset(BaseAdr, portadr[gstep], bautrat);
		  outportb(BaseAdr+portadr[gstep]+IER, 0x01);
		  while ((inportb(BaseAdr+portadr[gstep]+LSR) & 0x01) == 0x01)
			 inportb(BaseAdr+portadr[gstep]);
		  IndecontrolReg(BaseAdr,portadr[gstepn],0x0c,0x00);

		  UartsRegsset(BaseAdr, portadr[gstepn], bautrat);
		  outportb(BaseAdr+portadr[gstepn]+LCR, inportb(BaseAdr+portadr[gstepn]+LCR) & 0x7f);
		  outportb(BaseAdr+portadr[gstepn]+IER, 0x01);
		  while ((inportb(BaseAdr+portadr[gstepn]+LSR) & 0x01) == 0x01)
			 inportb(BaseAdr+portadr[gstepn]);

		  if (modevar == 6)
		  {
			  for (head2=tralevel; head2 != rb_size; head2++)//trigger empty trans
			  {
				   outportb(BaseAdr+portadr[gstepn], txbuf1[head2]);
			  }
		  }
		  else if (modevar == 4)
		  {
			  for (head2=(rb_size-titl650); head2 != rb_size; head2++)//trigger empty trans
			  {
				   outportb(BaseAdr+portadr[gstepn], txbuf1[head2]);
			  }
		  }
		  else
		  {
			   outport(BaseAdr+portadr[gstepn],txbuf1[1]);
			   head1=0;
		  }
		  if (display==1)
		  {
			  printf("PORT%d Interrupt received char number last char:",gstep+1);
			  x=wherex();
			  y=wherey();
		  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -