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

📄 ry.c

📁 开源的BIOS启动软件
💻 C
字号:
/* * Receive file with YMODEM file transfer protocol * * Note:  This code uses 8 bit checksum which may not be compatible with  *        some programs claiming to support YMODEM transfers. * * 1999/11/24  Nicolas Pitre <nico@cam.org>: *	Integrated into EBSA285's BIOS for ARM Linux. * */#include <bios/stdio.h>#include <bios/string.h>#include <bios/time.h>#include <bios/timer.h>#include <bios/boot.h>#include <bios/bootdev.h>#define SERBASE 0x42000160#define OK 0#define ERROR (-1)#define FALSE 0#define TRUE 1#define CAN ('X'&037)#define SOH 1#define STX 2#define EOT 4#define ACK 6#define NAK 025#define TIMEOUT (-2)#define RETRYMAX 15#define WCEOT (-10)static long Bytesleft;static int Blklen;static char secbuf[1024];static unsigned long *pout;static void tx( int c ){  while (*((volatile int *)(SERBASE + 0x18)) & (1<<5));  *((volatile int *)(SERBASE)) = c;}static int rx(int timeout){  int c;  unsigned int expire = centisecs + timeout * 100;  while( centisecs <= expire ){    if ( ! (*((volatile int *)(SERBASE + 0x18)) & (1<<4)) ) {      c = *((volatile int *)(SERBASE));      return c & 0xff;    }  }  return TIMEOUT;}static inline void putsec (char *p, int n){  n += 3;  n >>= 2;  while( n-- )    *pout++ = *((unsigned long *)p)++;}static int procheader (char *name){  register char *p;  Bytesleft = 0x7fffffff;  p = name + 1 + strnlen (name, 128);  if (*p)    Bytesleft = atol(p);  return OK;}static int wcgetsec (char *rxbuf){  register int checksum, wcj, firstch;  register char *p;  int sectcurr, errors;  for (errors = 0; errors < RETRYMAX; errors++)    {      if ((firstch = rx(5)) == STX)	{	  Blklen = 1024;	  goto get2;	}      if (firstch == SOH)	{	  Blklen = 128;	get2:	  sectcurr = rx(2);	  checksum = 0;	  if ((sectcurr + (rx(2))) == 0377)	    {	      for (p = rxbuf, wcj = Blklen; --wcj >= 0;)		{		  if ((firstch = rx(2)) < 0)		    goto bilge;		  checksum += (*p++ = firstch);		}	      if ((firstch = rx(2)) < 0)		goto bilge;	      if (((checksum - firstch) & 0377) == 0)		return sectcurr;	    }	}      else if (firstch == EOT)	return WCEOT;      else if (firstch == CAN)	return ERROR;    bilge:      while (rx(2) != TIMEOUT);      tx(NAK);    }  return ERROR;}static int wcrxpn (char *rpn){  register int c;   et_tu:  tx(NAK);  while ((c = wcgetsec (rpn)) != 0)    {      if (c == WCEOT)	{	  tx(ACK);	  rx(2);	  goto et_tu;	}      return ERROR;    }  tx(ACK);  return OK;}static int wcrx (){  register int sectnum, sectcurr, sendchar, cblklen;  sectnum = 0;  sendchar = NAK;  for (;;)    {      tx(sendchar);      sectcurr = wcgetsec (secbuf);      if (sectcurr == ((sectnum + 1) & 0377))	{	  sectnum++;	  cblklen = Bytesleft > Blklen ? Blklen : Bytesleft;	  putsec (secbuf, cblklen);	  if ((Bytesleft -= cblklen) < 0)	    Bytesleft = 0;	  sendchar = ACK;	}      else if (sectcurr == (sectnum & 0377))	sendchar = ACK;      else if (sectcurr == WCEOT)	{	  tx(ACK);	  return OK;	}      else if (sectcurr == ERROR)	return ERROR;      else	return ERROR;    }}static int wcreceive (){  for (;;)    {      if (wcrxpn (secbuf) == ERROR)	break;      if (secbuf[0] == 0)	return OK;      if (procheader (secbuf) == ERROR || wcrx () == ERROR)	break;    }  return ERROR;}static int serial_load( void ){  int res;  printf( "\nNow send file with y-modem (^X to abort) ...\n" );  pout = (unsigned long *)load_addr;  res = wcreceive();  wait_cs( 50 );  printf( "\nTransfer %s, press any key.\n",           (res == OK) ? "complete" : "failed" );  getc();  return res;}static int serial_dummy( void ){  return 0;}struct bootdev boot_serial = {        "serial",        serial_dummy,        serial_dummy,        serial_load,        serial_dummy};

⌨️ 快捷键说明

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