
#define SOH     '\x01'
#define STX     '\x02'
#define EOT     '\x04'
#define ACK     '\x06'
#define NAK     '\x15'
#define CAN     '\x18'
#define CRC     '\x43'
#define	CR	'\x0D'

#define	XM_FILE		0
#define	XM_FSIZE	2
#define	XM_TBLK		3
#define	XM_SSIZE	4
#define	XM_SBLK		5
#define	XM_RSIZE	6
#define	XM_RBLK		7
#define	XM_TMOVR	8
#define	XM_RETRY	9
/* ------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */

#define	CPMEOF	'\x1A'
#define YG      '\x47'

#define	XM_ERTIME	10
#define	XM_RATE		11
#define	XM_MSG		12
/*****
#define	XM_MSG		10
*****/
/* ---------------------------------------------------------------- */

#define	DSP_WAIT	50000

int	Recive()
{
    int      ch;
    unsigned int st;
    time_t   s,n;

    if ( RSB_Receive(port,&ch,&st) == 0 )
	return (ch & 0xff);

    time(&s);
    do {
	if ( RSB_Receive(port,&ch,&st) == 0 )
	    return (ch & 0xff);
	time(&n);
    } while ( (n - s) < 5 );

    return ERR;
}
static int  Recive_str(arg,n)
UCHAR	*arg;
int	n;
{
    int	    ch;

    while ( n-- > 0 ) {
        if ( (ch = Recive()) == ERR )
	    return ERR;
	*(arg++) = ch;
    }
    return FALSE;
}

/*************************************************
   <<< X-Modem UpLoad Abort Hit ESC Key >>>

File Name    A:WINK.EXP
File Size    xxxx	    Total Block  xxxx
Send Size    xxxx	    Send Block   xxxx
Recive Size  xxxx	    Recive Block xxxx
Time Over    xxxx	    ReTry Count  xxxx
Message      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

012345678901234567890123456789012345678901234567890
***************************************************/
void	Xmd_wind(md,file)
char	*md,*file;
{
    int    i;
    long   l;
    char   tmp[160];
    static char *menu[]={
	"File Name",	"",
	"File Size",	"Total Block",
	"Send Size",	"Send Block",
	"Recive Size",	"Recive Block",
	"Time Over",	"ReTry Count",
/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin -------------- */
	"Erapsed Time",	"Data Rate",
/* ---------------------------------------------------------------- */
	"Message",
	NULL
    };

/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
    Dmy_form(tmp,50,0x98,0x95,0x99); 
    wrtstr(tmp,15,7,0x05);
    Dmy_form(tmp,50,0x96,0x20,0x96); 
    for ( i = 0 ; i < 10 ; i++ )
        wrtstr(tmp,15,8+i,0x05);

    Dmy_form(tmp,50,0x9A,0x95,0x9B); 
    wrtstr(tmp,15,17,0x05);

    sprintf(tmp,"<<< X/Y-Modem %s Abort Hit ESC Key >>>",md);
    wrtstr(tmp,19,8,0x01);
/*****
    Dmy_form(tmp,50,0x98,0x95,0x99); 
    wrtstr(tmp,15,7,0x05);

    Dmy_form(tmp,50,0x96,0x20,0x96); 
    for ( i = 0 ; i < 9 ; i++ )
        wrtstr(tmp,15,8+i,0x05);

    Dmy_form(tmp,50,0x9A,0x95,0x9B); 
    wrtstr(tmp,15,17,0x05);

    sprintf(tmp,"<<< X-Modem %s Abort Hit ESC Key >>>",md);
    wrtstr(tmp,20,8,0x01);
*****/
/* ---------------------------------------------------------------- */

    for ( i = 0 ; menu[i] != NULL ; i++ )
	wrtstr(menu[i],17 + (i % 2) * 28,10 + i / 2,0x05);

    wrtstr(file,30,10,0x05);
}
void	Xmd_msg(msg)
char	*msg;
{
/* -------------------- DATA RATE 92/02/17 Pumpkin ---------------- */
    wrtstr(msg,30,16,0x05);
/*****
    wrtstr(msg,30,15,0x05);
*****/
/* ---------------------------------------------------------------- */
}
void	Xmd_val(no,val)
int	no;
long	val;
{
    char    tmp[40];
/* -------------------- DATA RATE 92/02/17 Pumpkin ---------------- */
    if (no == XM_ERTIME) {
	sprintf(tmp,"%02ld:%02ld:%02ld",val/3600,(val%3600)/60,val%60);
    } else {
    	sprintf(tmp,"%ld ",val);
    }
/*****
    sprintf(tmp,"%ld",val);
*****/
/* ---------------------------------------------------------------- */
    wrtstr(tmp,30 + (no % 2) * 28,10 + no / 2,0x05);

}

/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
int    	crcmode=FALSE;

#define W	16    /* CRCビット数 */
#define B	8     /* the number of bits per char */
#define crctab crc_table
extern unsigned short crctab[];
/* ---------------------------------------------------------------- */

static int Send_blk(fp,bk,bufsize)
FILE    *fp;
int     bk;
int	bufsize;
{
    int     i,j;
    UCHAR   head[3];

/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin -------------- */
    unsigned short crcsum;
    UCHAR   *p,tmp[1024];

    if (bufsize == 128) {
	    head[0]=SOH;
    } else {
	    head[0]=STX;
    }

    head[1]=bk;
    head[2]=255-bk;

    if ( (i=fread(tmp,1,bufsize,fp)) <= 0 ) {
	send_aux(EOT);
        return ERR;
    }

    for ( p=tmp+i ; i < bufsize ; i++ )
        *(p++)='\0';

    for ( crcsum = j = i = 0 ; i < bufsize ; i++ ) {
	if (crcmode==TRUE)  { /* CRC */
   	     crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
	} else {        /* checksum */
	     j += tmp[i]; j &= 0xff;
	}
    }

    send_str(head,3);
    send_str(tmp,bufsize);
    if (crcmode==TRUE)  { /* CRC */
    	send_aux(crcsum >> 8);
    	send_aux(crcsum & 255);
    } else {        /* checksum */
    	send_aux(j);
    }

/*******
    UCHAR   *p,tmp[128];

    head[0]=SOH;
    head[1]=bk;
    head[2]=255-bk;

    if ( (i=fread(tmp,1,128,fp)) <= 0 ) {
	send_aux(EOT);
        return ERR;
    }

    for ( p=tmp+i ; i < 128 ; i++ )
        *(p++)='\0';
    for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
        j += tmp[i];

    send_str(head,3);
    send_str(tmp,128);
    send_aux(j);
*******/
/* ---------------------------------------------------------------- */


    return FALSE;
}


/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
void    Up_Xmodem(file)
char    *file;
{
    int     i,ch,bk,nk,ef;
    unsigned int ec;
    FILE    *fp;
    long    size,remsize;
    int	    bufsize=128;
    char    tmp[80];
    time_t  fsttime,nowtime,*t=NULL;

    if (crcmode == TRUE) bufsize =1024;

    Xmd_wind("UpLoad",file);
    if ( (fp = fopen(file,"rb")) == NULL ) {
	Xmd_msg("File Not Found");
	Soft_Timer(DSP_WAIT);
	return;
    }
    fseek(fp,0L,2);
    remsize = size = (long)ftell(fp);
    fseek(fp,0L,0);
    Xmd_val(XM_FSIZE,size);
    i = size / bufsize;
    i += ((size - i * bufsize)+127) / 128;
    Xmd_val(XM_TBLK,i);
    fsttime = time(t);

    for ( bk = 1, nk = 0, ef = FALSE, size = 0 ; ; ) {
	if ( kbhit() != 0 ) {
	    ch = Get_key(&ec);
	    if ( ch == 0x1B || ec == 0x7200 ) {
		Xmd_msg("Abort Xmodem Upload !!");
	        send_aux(CAN);
		Soft_Timer(DSP_WAIT);
		break;
	    }
	}
	for ( i = 0 ; i < 5 ; i++ ) {
	    if ( (ch = Recive()) != ERR ) 
		break;
	    Xmd_val(XM_TMOVR,i);
	}
	if ( i >= 5 ) {
	    Xmd_msg("Time Over Aobrt !!");
	    Soft_Timer(DSP_WAIT);
	    break;
	}
	if ( ch == ACK) {
	    size += bufsize; remsize -= bufsize; nk = 0; bk++;

	    if ( ef != FALSE ) {
		Xmd_msg("End of Upload !!");
		break;
	    }
	    if ( remsize < 0 && bufsize == 1024) {
		remsize += bufsize;
	    	bufsize = 128;
	    }

	    if ( Send_blk(fp,bk,bufsize) != FALSE )
		ef = TRUE;
	    else {
		Xmd_val(XM_SSIZE,size + bufsize);
		Xmd_val(XM_SBLK,bk);
	    	nowtime = time(t);
	    	if ((nowtime-fsttime) != 0) {
	    		Xmd_val(XM_RATE,(size+bufsize)/(nowtime-fsttime));
	    	}
		Xmd_val(XM_ERTIME,(nowtime-fsttime));
	    }
	} else if ( ch == NAK  || ch == CRC ) {
	    if ( nk++ > 0 )
		Xmd_val(XM_RETRY,nk);
	    fseek(fp,size,SEEK_SET);
	    if ( Send_blk(fp,bk,bufsize) != FALSE )
		ef = TRUE;
	    else {
		Xmd_val(XM_SSIZE,size + bufsize);
		Xmd_val(XM_SBLK,bk);
	    	nowtime = time(t);
	    	if ((nowtime-fsttime) != 0) {
	    		Xmd_val(XM_RATE,(size+bufsize)/(nowtime-fsttime));
	    	}
		Xmd_val(XM_ERTIME,(nowtime-fsttime));
	    }
	} else if ( ch == CAN ) {
            Xmd_msg("Recive Cansel Code !!");
	    Soft_Timer(DSP_WAIT);
            break;
        }
        if ( nk >= 5 ) {
            Xmd_msg("ReTry Over Abort !!");
	    send_aux(CAN);
	    Soft_Timer(DSP_WAIT);
	    break;
	}
    }
    fclose(fp);
}

/**********
void    Up_Xmodem(file)
char    *file;
{
    int     i,ch,bk,nk,ef;
    unsigned int ec;
    FILE    *fp;
    long    size;
    char    tmp[80];

    Xmd_wind("UpLoad",file);
    if ( (fp = fopen(file,"rb")) == NULL ) {
	Xmd_msg("File Not Found");
	Soft_Timer(DSP_WAIT);
	return;
    }
    fseek(fp,0L,2);
    size = (long)ftell(fp);
    fseek(fp,0L,0);
    Xmd_val(XM_FSIZE,size);
    Xmd_val(XM_TBLK,(size + 127) / 128);

    for ( bk = 1, nk = 0, ef = FALSE, size = 0 ; ; ) {
	if ( kbhit() != 0 ) {
	    ch = Get_key(&ec);
	    if ( ch == 0x1B || ec == 0x7200 ) {
		Xmd_msg("Abort Xmodem Upload !!");
	        send_aux(CAN);
		Soft_Timer(DSP_WAIT);
		break;
	    }
	}
	for ( i = 0 ; i < 5 ; i++ ) {
	    if ( (ch = Recive()) != ERR ) 
		break;
	    Xmd_val(XM_TMOVR,i);
	}
	if ( i >= 5 ) {
	    Xmd_msg("Time Over Aobrt !!");
	    Soft_Timer(DSP_WAIT);
	    break;
	}
	if ( ch == ACK ) {
	    size += 128; nk = 0; bk++;
	    if ( ef != FALSE ) {
		Xmd_msg("End of Upload !!");
		break;
	    }
	    if ( Send_blk(fp,bk) != FALSE )
		ef = TRUE;
	    else {
		Xmd_val(XM_SSIZE,size + 128);
		Xmd_val(XM_SBLK,bk);
	    }
	} else if ( ch == NAK ) {
	    if ( nk++ > 0 )
		Xmd_val(XM_RETRY,nk);
	    fseek(fp,size,SEEK_SET);
	    if ( Send_blk(fp,bk) != FALSE )
		ef = TRUE;
	    else {
		Xmd_val(XM_SSIZE,size + 128);
		Xmd_val(XM_SBLK,bk);
	    }
	} else if ( ch == CAN ) {
            Xmd_msg("Recive Cansel Code !!");
	    Soft_Timer(DSP_WAIT);
            break;
        }
        if ( nk >= 5 ) {
            Xmd_msg("ReTry Over Abort !!");
	    send_aux(CAN);
	    Soft_Timer(DSP_WAIT);
	    break;
	}
    }
    fclose(fp);
}
*********/
/* ---------------------------------------------------------------- */

void	Down_Xmodem(file)
char	*file;
{
    int     i,j,ch,bk,nk,ef;
    unsigned int ec;
    long    size;
    FILE    *fp;
/* --------------XMODEM 1024/CRC 92/02/17 Pumpkin ----------------- */
    time_t  fsttime,nowtime,*t=NULL;
    int	    bufsize = 128,k,sectnum,sectcur;
    unsigned short crcsum;
    UCHAR   tmp[1024];
/**********
    UCHAR   tmp[128];
*********/
/* ---------------------------------------------------------------- */

    Xmd_wind("DownLoad",file);
    if ( (fp = fopen(file,"wb")) == NULL ) {
	wrtstr("ﾌｧｲﾙが作成出来ません",30,1,0x12);
	return;
    }
/* ----------------- DATA RATE 92/02/17 Pumpkin ----------------- */
    fsttime = time(t);
/* ---------------------------------------------------------------- */
    for ( ef = TRUE,bk = 1,size = 0,nk = 0 ; ; ) {
	if ( kbhit() != 0 ) {
	    ch = Get_key(&ec);
	    if ( ch == 0x1B || ec == 0x7200 ) {
		Xmd_msg("Abort Xmodem Download !!");
	        send_aux(CAN);
		Soft_Timer(DSP_WAIT);
		break;
	    }
	}
	for ( i = 0 ; i < 5 ; i++ ) {
/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin ----------------- */
	    if (crcmode==TRUE && (bk==1 || bk==2))  { /* CRC */
		send_aux(CRC);
	    } else {
	    	if ( ef == FALSE )
			send_aux(ACK);
	    	else if ( Flaing == FALSE )
			send_aux(NAK);
	    	else {
			send_aux(NAK); send_aux(ACK);
	    	}
	    }
/**************
	    if ( ef == FALSE )
		send_aux(ACK);
	    else if ( Flaing == FALSE )
		send_aux(NAK);
	    else {
		send_aux(NAK); send_aux(ACK);
	    }
**************/
/* ---------------------------------------------------------------- */
	    if ( (ch = Recive()) != ERR ) 
		break;
	    Xmd_val(XM_TMOVR,i);
	}

	if ( i >= 5 ) {
	    Xmd_msg("Time Over Abort !!");
	    Soft_Timer(DSP_WAIT);
	    break;
	}

	if ( ch == EOT ) {
	    Xmd_msg("End of DownLoad !!");
	    if ( Flaing == FALSE )
		send_aux(ACK);
	    break;
	} else if ( ch == CAN ) {
            Xmd_msg("Recive Cansel Code !!");
	    Soft_Timer(DSP_WAIT);
            break;
/* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin ----------------- */
        } else if ( ch == SOH || ch == STX ) {
	    bufsize = (ch == SOH) ? 128 : 1024;
	    if (bk==1) {
	    	if (ch == SOH && crcmode==TRUE) Xmd_msg("X-Modem 128/CRC");
	    	if (ch == STX && crcmode==TRUE) Xmd_msg("X-Modem 1024/CRC");
	    	if (ch == SOH && crcmode==FALSE) Xmd_msg("X-Mmodem 128/SUM");
	    	if (ch == STX && crcmode==FALSE) Xmd_msg("X-Modem 1024/SUM");
  	    }

	    sectcur = Recive();
            if ( (sectcur + Recive()) != 0xff ) {
       		Xmd_msg("PacNo. SUM Error");
		goto ERROR;
	    }
            if ( sectcur != (bk & 0xff) ) {
		sprintf((char *)tmp,"PacNo. Err rcv=%4d cal=%4d",sectcur,bk);
       		Xmd_msg((char *)tmp);
		goto ERROR;
	    }
	    if ( Recive_str(tmp,bufsize) != FALSE ) {
       		Xmd_msg("Data Read Error");
		goto ERROR;
	    }
	    for ( crcsum = j = i = 0 ; i < bufsize ; i++ ) {
		if (crcmode==TRUE)  { /* CRC */
	   	     crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
		} else {        /* checksum */
		     j += tmp[i]; j &= 0xff;
		}
	    }

	    if (crcmode==TRUE) { /* CRC */
		k = Recive(); k = (k<<8) | Recive();
	    	if ( k != crcsum ) {
			sprintf((char *)tmp,"CRC Err rcv=%4X cal=%4X",k,crcsum);
            		Xmd_msg((char *)tmp);
			goto ERROR;
		}
	    } else {
	    	if ( Recive() != j ) {
            		Xmd_msg("Check SUM Error");
			goto ERROR;
		}
	    }
		

	    fwrite(tmp,1,bufsize,fp);
	    size += bufsize;

	    nowtime = time(t);
	    if ((nowtime-fsttime) != 0) {
	    	Xmd_val(XM_RATE,size/(nowtime-fsttime));
	    }
	    Xmd_val(XM_ERTIME,(nowtime-fsttime));

	    Xmd_val(XM_RSIZE,size);
	    Xmd_val(XM_RBLK,bk);
	    ef = FALSE;
	    nk = 0;
	    bk ++;
	    continue;
	}

	sprintf((char *)tmp,"Undefined Code %2X     ",ch);
	Xmd_msg(tmp);

ERROR:  Recive_str(tmp,bufsize); /* Dummy */

/**********
        } else if ( ch == SOH ) {
            if ( Recive() != (bk & 0xff) )
		goto ERROR;
            if ( (255 - Recive()) != (bk & 0xff) )
		goto ERROR;
	    if ( Recive_str(tmp,128) != FALSE )
		goto ERROR;
	    for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
		j += tmp[i];
	    if ( Recive() != j )
		goto ERROR;

	    fwrite(tmp,1,128,fp);
	    size += 128;
	    Xmd_val(XM_RSIZE,size);
	    Xmd_val(XM_RBLK,bk);
	    ef = FALSE;
	    nk = 0;
	    bk++;
	    continue;
	}

ERROR:  Recive_str(tmp,128);	/+ Dummy +/
*********/
/* ---------------------------------------------------------------- */

	ef = TRUE;
	Xmd_val(XM_RETRY,++nk);
        if ( nk >= 5 ) {
            Xmd_msg("ReTry Over Abort !!");
	    send_aux(CAN);
	    Soft_Timer(DSP_WAIT);
	    break;
	}
    }
    fclose(fp);
}

void	Down_Ymodem()
{
    int     i,j,ch,bk,nk,ef;
    unsigned int ec;
    time_t  fsttime,nowtime,*t=NULL;
    long    size, filesize, modtime, filemode;
    FILE    *fp;
    int	    bufsize = 128,k,sectnum,sectcur;
    unsigned short crcsum;
    char	tmp[1024],file[128],*p,crc;


    if ( Flaing == FALSE )  crc = CRC; else crc = YG;
    Xmd_wind("DownLoad","");
    for ( ef = TRUE,bk = 0,size = 0,nk = 0 ; ; ) {
	if ( kbhit() != 0 ) {
	    ch = Get_key(&ec);
	    if ( ch == 0x1B || ec == 0x7200 ) {
		Xmd_msg("Abort Ymodem Download !!");
	        send_aux(CAN);
		Soft_Timer(DSP_WAIT);
		break;
	    }
	}
	for ( i = 0 ; i < 5 ; i++ ) {
	    if (bk==0 || bk==1)  { /* CRC */
		send_aux(crc);
	    } else {
    		if ( Flaing == FALSE ) {
		    	if ( ef == FALSE ) {
				send_aux(ACK);
	    		} else{
				send_aux(NAK);
	    		}
	    	}
	    }
	    if ( (ch = Recive()) != ERR ) 
		break;
	    Xmd_val(XM_TMOVR,i);
	}

	if ( i >= 5 ) {
	    Xmd_msg("Time Over Aobrt !!");
	    Soft_Timer(DSP_WAIT);
	    break;
	}

	if ( ch == EOT ) {
	    Xmd_msg("End of DownLoad !!");
	    send_aux(ACK); send_aux(crc);
	    if ( Flaing != FALSE ) {
	    	ch = Recive();
		bufsize = (ch == SOH) ? 128 : 1024;
		Recive_str(tmp,bufsize+4); /* Dummy */
	    }
	    break;
	} else if ( ch == CAN ) {
            Xmd_msg("Recive Cansel Code !!");
	    Soft_Timer(DSP_WAIT);
            break;
        } else if ( ch == SOH || ch == STX ) {
	    bufsize = (ch == SOH) ? 128 : 1024;

	    sectcur = Recive();
            if ( (sectcur + Recive()) != 0xff ) {
       		Xmd_msg("PacNo. SUM Error");
		goto ERROR;
	    }
            if ( sectcur != 0 && sectcur != (bk & 0xff) ) {
		sprintf((char *)tmp,"PacNo. Err rcv=%4d cal=%4d",sectcur,bk);
       		Xmd_msg(tmp);
		goto ERROR;
	    }
	    if ( Recive_str(tmp,bufsize) != FALSE ) {
       		Xmd_msg("Data Read Error");
		goto ERROR;
	    }
	    for ( crcsum = i = 0 ; i < bufsize ; i++ ) {
   	    	crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
	    }

	    /* CRC */
	    k = Recive(); k = (k<<8) | Recive();
	    if ( k != crcsum ) {
            	Xmd_msg("CRC Error");
		goto ERROR;
	    }


	    if (sectcur == 0) {	/*ヘッダの場合*/
		strcpy(file, (char *)tmp);
		p = tmp + strlen(tmp) + 1;
		sscanf(p, "%ld%lo%o", &filesize, &modtime, &filemode);

		Xmd_wind("DownLoad",file);
		Xmd_val(XM_FSIZE,filesize);
		if ( Flaing == FALSE ) {
			Xmd_msg("Y-Modem/1024");
		}else{
			Xmd_msg("Y-Modem-g");
		}
		i = filesize / 1024;
		i += ((filesize - i * 1024)+127) / 128;
    		Xmd_val(XM_TBLK,i);

    		if ( (fp = fopen(file,"wb")) == NULL ) {
			wrtstr("ﾌｧｲﾙが作成出来ません",30,1,0x12);
		    	send_aux(CAN); send_aux(CAN); send_aux(CAN);
	    		Soft_Timer(DSP_WAIT);
	    		break;
		}
	    	fsttime = time(t);

	    } else {
		    if (filesize >= (size + bufsize)) {
			    fwrite(tmp,1,bufsize,fp);
		   	    size += bufsize;
		    }else{
			    fwrite(tmp,1,(filesize - size),fp);
		   	    size = filesize;
		    }
	    }

	    nowtime = time(t);
	    if ((nowtime-fsttime) != 0) {
	    	Xmd_val(XM_RATE,size/(nowtime-fsttime));
	    }
	    Xmd_val(XM_ERTIME,(nowtime-fsttime));
	    Xmd_val(XM_RSIZE,size);
	    Xmd_val(XM_RBLK,bk);
	    ef = FALSE;
	    nk = 0;
	    bk ++;
	    continue;
	}

	sprintf((char *)tmp,"Undefined Code %2X     ",ch);
	Xmd_msg(tmp);

ERROR:  Recive_str(tmp,bufsize); /* Dummy */
	ef = TRUE;
	Xmd_val(XM_RETRY,++nk);
        if ( nk >= 5 ) {
            Xmd_msg("ReTry Over Abort !!");
	    send_aux(CAN);
	    Soft_Timer(DSP_WAIT);
	    break;
	}
    }
    fclose(fp);
}

/**************************
    Auto Login
**************************/
int	htob(ch)
int     ch;
{
    int     i=0;

    if ( ch >= 'a' && ch <= 'z' )
	ch &= 0xDF;
    if ( '0' <= ch && ch <= '9' )
        i = ch - '0';
    else if ( 'A' <= ch && ch <= 'F' )
        i = ch - 'A' + 10;
    return i;
}
int	Wait_recive(tick)
int	tick;
{
    int     len,ch;
    unsigned int st;
    time_t  l,s;

    time(&l); l += tick;
    do {
	RSB_Read(port,&len);
    	if ( len > 0 ) {
	    RSB_Receive(port,&ch,&st);
	    BakPut(ch); Dsp_vram(cvram);
	    return ch;
	}
	time(&s);
    } while ( kbhit() == 0 && s < l );
    return ERR;
}
void	RS_Sleep(tick)
int	tick;
{
    int     len,ch;
    unsigned int st;
    time_t  l,s;

    time(&l); l += tick;
    do {
	RSB_Read(port,&len);
    	if ( len > 0 ) {
	    while ( len-- > 0 ) {
	        RSB_Receive(port,&ch,&st);
	        BakPut(ch);
	    }
	    Dsp_vram(cvram);
	}
	time(&s);
    } while ( kbhit() == 0 && s < l );
}
int	cmpstr(arg)
char    *arg;
{
    int     ch,wt;
    register char    *p;

    for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
	wt = wt * 10 + *p - '0';
    if ( *p == ',' && wt > 0 )
	arg = p + 1;
    else
	wt = 30;

    for ( p=arg ; *p != ']' ; ) {
        if ( (ch=Wait_recive(wt)) == ERR )
            return ERR;
        if ( ch == (*p & 0xff) )
            p++;
        else
            p=arg;
    }
    return FALSE;
}
int	cmpmac(arg)
char    *arg;
{
    int     ch,wt;
    register char    *p;

    for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
	wt = wt * 10 + *p - '0';
    if ( *p == ',' && wt > 0 )
	arg = p + 1;
    else
	wt = 5;

    for ( p=arg ; *p != '}' ; ) {
        if ( (ch=Wait_recive(wt)) == ERR )
            return ERR;
        if ( ch == (*p & 0xff) )
            p++;
        else
            p=arg;
    }
    return FALSE;
}
int	runlog(arg)
register char    *arg;
{
    int     ch;
    char    *p;
    char    *adr=NULL;

    for ( ; *arg != '\0' ; arg++ ) {
        switch(*arg) {
            case '<':
                send_aux(CR);
                break;
            case '>':
                while ( (ch=Wait_recive(30)) != CR ) {
		    if ( ch == ERR )
			return ERR;
                    if ( kbhit() != 0 )
                        return TRUE;
                }
                break;
            case '$':
                send_aux( htob(*(++arg)) << 4 | htob(*(++arg)) );
                break;
            case '\\':
                send_aux(*(++arg));
                break;
            case '*':
                RS_Sleep(2);
                break;
            case '?':
		adr = arg;
		break;
            case '@':
		adr = NULL;
		break;
            case '[':
                if ( cmpstr(++arg) != FALSE )
                    return ERR;
                while ( *arg != ']' ) arg++;
                break;
            case '{':
		if ( adr == NULL ) {
                    for ( p = arg ; *p != '?' && *p != '\0' ; p++ )
		    if ( *p == '?' )
		        adr = p;
		    else
		        return ERR;
		}
                if ( cmpmac(++arg) != FALSE ) {
		    if ( kbhit() != 0 )
			return ERR;
		    arg = adr;
		} else
                    while ( *arg != '}' ) arg++;
                break;
            default:
                send_aux(*arg);
                break;
        }
        if ( kbhit() != 0 )
            return TRUE;
    }
    return FALSE;
}
char    *Auto_menu[21]={ NULL };
char    *Auto_para[21];

void	Auto_log()
{
    static int  no=ERR;

    if ( Auto_menu[0] == NULL )
	goto ENDOF;

    if ( Sel_menu(Auto_menu,20,2,&no) != FALSE )
	goto ENDOF;

    wrtstr(SPCSTR,30,1,0x1F);
    if ( runlog(Auto_para[no]) == ERR )
	wrtstr("オ−トを中断しました",30,1,0x15);

ENDOF:
    Dsp_vram(cvram);
    Dsp_free();
}

char	*Auto_log_file="WINK.DEF";

void	Auto_log_init()
{
    int     i,mx=0;
    FILE    *fp;
    char    *p,*s,*n;
    char    tmp[256];
    char    work[4096];

    if ( (p = getenv("WINKAUTO")) != NULL )
	Auto_log_file = p;

    if ( (fp = fopen(Auto_log_file,"r")) == NULL )
	return;

    while ( (p = fgets(tmp,256,fp)) != NULL ) {
	while ( isspace(*p) ) p++;
	while ( p != NULL && *p == '#' ) {
	    for ( s = ++p ; *s != '\n' && *s != '\0' ; s++ );
	    *s = '\0';
	    if ( (n = Auto_menu[mx] = (char *)malloc(22)) == NULL )
		goto ENDOF;
	    for ( i = 0 ; i < 20 && *p != '\0' ; i++ )
		*(n++) = *(p++);
	    for ( ; i < 20 ; i++ )
		*(n++) = ' ';
	    *n = '\0';
	    for ( s = work ; (p = fgets(tmp,256,fp)) != NULL ; ) {
		while ( isspace(*p) ) p++;
		if ( *p == '#' )
		    break;
		while ( *p != '\n' && *p != '\0' )
		    *(s++) = *(p++);
	    }
	    *s = '\0';
	    if ( (Auto_para[mx] = (char *)malloc(strlen(work)+1)) == NULL )
		goto ENDOF;
	    strcpy(Auto_para[mx],work);
	    if ( ++mx >= 20 )
	        goto ENDOF;
	}
    }
ENDOF:
    fclose(fp);
    Auto_menu[mx] = NULL;
}
