#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>
#include    <string.h>
#include    <ctype.h>
#include    <fmc.h>
#include    <mos.h>
#include    "dir.h"
#include    "scrn.h"
#include    "keyword.h"
#include    "graphic.h"
#include    "event.h"
#include    "coldef.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

#define	LIN_MAX		80
#define	TAB		8
#define	LPT_LINE	59

#define	PAGE		0x40000

#define	MAX_Y		25
#define	SCRN_Y		52

#define	SCRN_X1		0
#define	SCRN_Y1		47
#define	SCRN_X2		639
#define	SCRN_Y2		454

#define	BAR_SIZ		(25*8)
#define	BAR_X1		8
#define	BAR_Y1		458
#define	BAR_X2		(BAR_X1+BAR_SIZ+4)
#define	BAR_Y2		(BAR_Y1+19)

#define	KAKU_X1		(15*8-4)
#define	KAKU_Y1		180
#define	KAKU_X2		(64*8+3)
#define	KAKU_Y2		280

#define	KAKU_MSG_X	((KAKU_X1+KAKU_X2)/2)
#define	KAKU_MSG_Y	(KAKU_Y1+30)

#define	KAKU_CHK_X	((KAKU_X1+KAKU_X2)/2-(4*8))
#define	KAKU_CHK_Y	(KAKU_Y1+70)

#define	KAKU_YES_X	((KAKU_X1+KAKU_X2)/2-(10*8))
#define	KAKU_YES_Y	(KAKU_Y1+70)

#define	KAKU_NO_X	((KAKU_X1+KAKU_X2)/2+(2*8))
#define	KAKU_NO_Y	(KAKU_Y1+70)

#define	BREAK_X1	(13*8-4)
#define	BREAK_Y1	160
#define	BREAK_X2	(66*8+3)
#define	BREAK_Y2	300

#define	BREAK_MSG_X	((BREAK_X1+BREAK_X2)/2)
#define	BREAK_MSG_Y	(BREAK_Y1+30)

#define	BREAK_BAR_SIZ	(41*8)
#define	BREAK_BAR_X	(BREAK_X1+6*8)
#define	BREAK_BAR_Y	(BREAK_Y1+70)

#define	BREAK_BAR_X1	(BREAK_BAR_X-2)
#define	BREAK_BAR_Y1	(BREAK_BAR_Y-2)
#define	BREAK_BAR_X2	(BREAK_BAR_X+BREAK_BAR_SIZ+2)
#define	BREAK_BAR_Y2	(BREAK_BAR_Y+17)

#define	BREAK_CHK_X	((BREAK_X1+BREAK_X2)/2-(4*8))
#define	BREAK_CHK_Y	(BREAK_Y1+110)

typedef struct _LP {
    struct _LP	*next;
    struct _LP	*back;
    char        buf[1];
} LINPTR;

void	INKEY_start(void);
void	INKEY_end(void);
int	getch(void);
int	CLIP_box();

extern int	cur_x;
extern int	cur_y;

       int      cut_mode = FALSE;
       char     cut_buf[2][128];

static int	old_line=(-1);
static int	now_line=0;
static int	max_line=0;
static int	now_ofs=0;
static int	slow_ofs=0;
static int	tik_speed=100;
static int	scr_speed=16;
static int	pas_flg=FALSE;
static int	bar_old_x1=(-1);
static int	bar_old_x2=(-1);
static LINPTR	*top_ptr=NULL;
static LINPTR	*now_ptr=NULL;
static BLOCK	*save=NULL;
static char	file_name[128];
static int	break_bar=0;
static BLOCK	*break_save=NULL;
static EVENT	*break_ep=NULL;

int	pause(char *form,...)
{
    va_list arg;
    int     n,x1,x2;
    int     cd,sw,bx,by;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    va_end(arg);

    if ( (n = (strlen(tmp) * 8 + 32) / 2) < 160 )
	n = 160;
    x1 = (KAKU_X1 + KAKU_X2) / 2 - n;
    x2 = (KAKU_X1 + KAKU_X2) / 2 + n;

    MOS_disp(OFF);
    sp = DSP_push_vram(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_opbox(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_wbox(x1,KAKU_Y1,x2,KAKU_Y2,LINE_COL,FILD_COL,M_PSET);
    gputs(KAKU_MSG_X-strlen(tmp)*4,KAKU_MSG_Y,CHR_COL,FILD_COL,tmp);

    ep = EVT_sw(ep,0,KAKU_YES_X,KAKU_YES_Y,CHR_COL,WIND_COL," 続  行 ");
    ep = EVT_sw(ep,1,KAKU_NO_X,KAKU_NO_Y,CHR_COL,WIND_COL,  " 中  断 ");

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((KAKU_X1+KAKU_X2)/2,KAKU_YES_Y+8);
    MOS_disp(ON);

    cd = (EVT_wait(ep) == 0 ? TRUE:ERR);
    EVT_free(ep);

    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(x1,KAKU_Y1,x2,KAKU_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);

    return cd;
}
int	yesno2(char *form,...)
{
    va_list arg;
    int     n,x1,x2;
    int     cd,sw,bx,by;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    va_end(arg);

    if ( (n = (strlen(tmp) * 8 + 32) / 2) < 160 )
	n = 160;
    x1 = (KAKU_X1 + KAKU_X2) / 2 - n;
    x2 = (KAKU_X1 + KAKU_X2) / 2 + n;

    MOS_disp(OFF);
    sp = DSP_push_vram(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_opbox(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_wbox(x1,KAKU_Y1,x2,KAKU_Y2,LINE_COL,FILD_COL,M_PSET);
    gputs(KAKU_MSG_X-strlen(tmp)*4,KAKU_MSG_Y,CHR_COL,FILD_COL,tmp);

    ep = EVT_sw(ep,0,KAKU_YES_X,KAKU_YES_Y,CHR_COL,WIND_COL," は〜い ");
    ep = EVT_sw(ep,1,KAKU_NO_X,KAKU_NO_Y,CHR_COL,WIND_COL,  " いいえ ");

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((KAKU_X1+KAKU_X2)/2,KAKU_YES_Y+8);
    MOS_disp(ON);

    cd = (EVT_wait(ep) == 0 ? TRUE:ERR);
    EVT_free(ep);

    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(x1,KAKU_Y1,x2,KAKU_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);

    return cd;
}
int	yesno(char *form,...)
{
    va_list arg;
    int     n,x1,x2;
    int     cd,sw,bx,by;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    va_end(arg);

    if ( (n = (strlen(tmp) * 8 + 32) / 2) < 160 )
	n = 160;
    x1 = (KAKU_X1 + KAKU_X2) / 2 - n;
    x2 = (KAKU_X1 + KAKU_X2) / 2 + n;

    MOS_disp(OFF);
    sp = DSP_push_vram(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_opbox(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_wbox(x1,KAKU_Y1,x2,KAKU_Y2,LINE_COL,FILD_COL,M_PSET);
    gputs(KAKU_MSG_X-strlen(tmp)*4,KAKU_MSG_Y,CHR_COL,FILD_COL,tmp);

    ep = EVT_sw(ep,0,KAKU_YES_X,KAKU_YES_Y,CHR_COL,WIND_COL," 実  行 ");
    ep = EVT_sw(ep,1,KAKU_NO_X,KAKU_NO_Y,CHR_COL,WIND_COL,  " 取  消 ");

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((KAKU_X1+KAKU_X2)/2,KAKU_YES_Y+8);
    MOS_disp(ON);

    cd = (EVT_wait(ep) == 0 ? TRUE:ERR);
    EVT_free(ep);

    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(x1,KAKU_Y1,x2,KAKU_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);

    return cd;
}
void	kakunin(char *form,...)
{
    va_list arg;
    int     n,x1,x2;
    int     sw,bx,by;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    va_end(arg);

    if ( (n = (strlen(tmp) * 8 + 32) / 2) < 160 )
	n = 160;
    x1 = (KAKU_X1 + KAKU_X2) / 2 - n;
    x2 = (KAKU_X1 + KAKU_X2) / 2 + n;

    MOS_disp(OFF);
    sp = DSP_push_vram(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_opbox(x1,KAKU_Y1,x2,KAKU_Y2);
    DSP_wbox(x1,KAKU_Y1,x2,KAKU_Y2,ERR_COL,FILD_COL,M_PSET);
    gputs(KAKU_MSG_X-strlen(tmp)*4,KAKU_MSG_Y,ERR_COL,FILD_COL,tmp);

    ep = EVT_sw(ep,0,KAKU_CHK_X,KAKU_CHK_Y,ERR_COL,WIND_COL," 確  認 ");

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((KAKU_X1+KAKU_X2)/2,KAKU_CHK_Y+8);
    MOS_disp(ON);

    EVT_wait(ep);
    EVT_free(ep);

    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(x1,KAKU_Y1,x2,KAKU_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);
}
void	BREAK_open(char *form,...)
{
    va_list arg;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    va_end(arg);

    MOS_disp(OFF);
    break_save = DSP_push_vram(BREAK_X1,BREAK_Y1,BREAK_X2,BREAK_Y2);
    DSP_opbox(BREAK_X1,BREAK_Y1,BREAK_X2,BREAK_Y2);
    DSP_wbox(BREAK_X1,BREAK_Y1,BREAK_X2,BREAK_Y2,
					LINE_COL,FILD_COL,M_PSET);
    DSP_rbox(BREAK_BAR_X1,BREAK_BAR_Y1,BREAK_BAR_X2,BREAK_BAR_Y2,
					LINE_COL,WIND_COL,M_PSET);
    gputs(BREAK_MSG_X-strlen(tmp)*4,BREAK_MSG_Y,
					CHR_COL,FILD_COL,tmp);
    break_ep = EVT_sw(NULL,0,BREAK_CHK_X,BREAK_CHK_Y,
					CHR_COL,WIND_COL," 中  断 ");
    DSP_mos(2);
    MOS_disp(ON);

    break_bar = (-1);
    EVT_msg_no = ERR;
}
int	BREAK_chk(int max,int pos)
{
    int     n;

    if ( (n = (max > 0 ? (BREAK_BAR_SIZ * pos / max):0)) != break_bar ) {
	MOS_disp(OFF);
	DSP_box(BREAK_BAR_X,BREAK_BAR_Y,
		BREAK_BAR_X+n,BREAK_BAR_Y+15,7,M_PSET);
	MOS_disp(ON);
	break_bar = n;
    }

    EVT_loop(break_ep);

    return (EVT_msg_no == 0 ? TRUE:FALSE);
}
void	BREAK_close(void)
{
    EVT_free(break_ep); break_ep = NULL;
    MOS_disp(OFF);
    DSP_pop_vram(break_save);
    DSP_clbox(BREAK_X1,BREAK_Y1,BREAK_X2,BREAK_Y2);
    DSP_mos(0);
    MOS_disp(ON);
}
static LINPTR  *get_ptr(str)
char    *str;
{
    register LINPTR *lp;

    if ( (lp = (LINPTR *)malloc(strlen(str)+sizeof(LINPTR))) != NULL ) {
        lp->next = lp->back = NULL;
	strcpy(lp->buf,str);
    }
    return lp;
}
static LINPTR  *read_line(fp)
FILE    *fp;
{
    int     i,j,ch;
    char    tmp[LIN_MAX + 1];

    for ( i = 0 ; i < LIN_MAX ; ) {
        if ( (ch = getc(fp)) == EOF || ch == '\n' )
            break;
	if ( iskanji(ch) ) {
            if ( i == (LIN_MAX - 1) ) {
                ungetc(ch,fp);
		break;
            }
	    tmp[i++] = ch;
            if ( (ch = getc(fp)) == EOF ) {
                i--;
                break;
            }
            tmp[i++] = ch;
        } else if ( ch == '\t' ) {
	    j = TAB - (i % TAB);
	    while ( i < LIN_MAX && j-- > 0 )
		tmp[i++] = ' ';
	} else
	    tmp[i++] = ch;
    }
    tmp[i] = '\0';

    if ( tmp[0] == '\0' && feof(fp) )
	return NULL;

    return get_ptr(tmp);
}
static LINPTR	*read_file(file)
char    *file;
{
    FILE    *fp;
    LINPTR  *lp;
    LINPTR  tp;
    char    *p;

    file_name[0] = '\0';

    if ( file == NULL || (fp = fopen(file,"r")) == NULL )
	return NULL;

    strcpy(file_name,file);
    if ( (p = strrchr(file_name,'\\')) != NULL )
	*p = '\0';

    lp = &tp;
    while ( (lp->next = read_line(fp)) != NULL ) {
	lp->next->back = lp;
	lp = lp->next;
	max_line++;
    }

    fclose(fp);
    if ( tp.next != NULL )
	tp.next->back = NULL;
    return tp.next;
}
static void	free_file(LINPTR *tp)
{
    LINPTR *lp;

    while ( tp != NULL ) {
	lp = tp->next;
	free(tp);
	tp = lp;
    }
}
static void	scrool_bar_disp(void)
{
    int     x1,x2,s;

    if ( (s = max_line - now_line) > MAX_Y )
	s = MAX_Y;

    if ( bar_old_x1 == (-1) )
	DSP_rbox(BAR_X1,BAR_Y1,BAR_X2,BAR_Y2,LINE_COL,PRG_COL,M_PSET);
    else
	DSP_box(bar_old_x1,BAR_Y1+2,bar_old_x2,BAR_Y2-2,PRG_COL,M_PSET);

    if ( max_line > 0 ) {
        x1 = BAR_X1 + 2 + BAR_SIZ * now_line / max_line;
        x2 = BAR_X1 + 2 + BAR_SIZ * (now_line + s) / max_line;
	DSP_box(x1,BAR_Y1+2,x2,BAR_Y2-2,XPRG_COL,M_PSET);
	bar_old_x1 = x1;
	bar_old_x2 = x2;
    }

    MENU_mask(BACK_NO,now_line > 0 ? ON:OFF);
    MENU_mask(NEXT_NO,(now_line + MAX_Y) < max_line ? ON:OFF);
}
static void	FILE_disp(int line)
{
    int     i;
    LINPTR  *tp;

    while ( line > now_line && now_ptr != NULL && now_ptr->next != NULL ) {
	now_line++;
	now_ptr = now_ptr->next;
    }
    while ( line < now_line && now_ptr != NULL && now_ptr->back != NULL ) {
	now_line--;
	now_ptr = now_ptr->back;
    }

    if ( old_line == now_line )
	return;
    old_line = now_line;

    MOS_disp(OFF);
    now_ofs += slow_ofs; now_ofs &= 511;
    slow_ofs = 0;
    DSP_offset(1,0,(now_ofs - SCRN_Y)&511);
    tp = now_ptr;
    for ( i = 0 ; i < MAX_Y ; i++ ) {
	if ( tp != NULL ) {
	    putstr(tp->buf,PAGE,(i*16+now_ofs)&511);
	    tp = tp->next;
	} else
	    putstr("",PAGE,(i*16+now_ofs)&511);
    }
    scrool_bar_disp();
    MOS_disp(ON);
}
void	FILE_open(char *file)
{
    MOS_disp(OFF);
    if ( save == NULL )
	save = DSP_push_vram(SCRN_X1,SCRN_Y1,SCRN_X2,479);
    DSP_box(SCRN_X1,SCRN_Y1,SCRN_X2,SCRN_Y2,SCRN_COL,M_PSET);
    gputs(192,220,MENU_COL,SCRN_COL,"テキストファイルを読み込み中です");
    DSP_mos(2);
    MOS_disp(ON);

    free_file(top_ptr);
    bar_old_x1 = bar_old_x2 = old_line = (-1);
    max_line = now_line = 0;
    scr_speed = 16;
    slow_ofs = now_ofs = 0;
    top_ptr = now_ptr = read_file(file);
    cut_buf[0][0] = cut_buf[1][0] = '\0';
    FILE_disp(now_line);

    MOS_disp(OFF);
    DSP_offset(1,0,(now_ofs - SCRN_Y)&511);
    DSP_box(0,SCRN_Y,639,SCRN_Y+MAX_Y*16-1,0,M_PSET);
    gprintf(49*8,460,XPRG_COL,PRG_COL,"%-30.30s",file_name);
    DSP_mos(0);
    MOS_disp(ON);
    MENU_mask(PRNT_NO,top_ptr == NULL ? OFF:ON);
}
void	FILE_close(void)
{
    free_file(top_ptr);
    top_ptr = now_ptr = NULL;
    MOS_disp(OFF);
    DSP_pop_vram(save);
    DSP_clear(1);
    MOS_disp(ON);
    save = NULL;
}
void	FILE_back(void)
{
    if ( top_ptr == NULL || now_line <= 0 )
	return;
    FILE_disp(now_line - MAX_Y);
}
void	FILE_next(void)
{
    if ( top_ptr == NULL || (now_line + MAX_Y) >= max_line )
	return;
    FILE_disp(now_line + MAX_Y);
}
static void	FILE_one_up(void)
{
    int     i;
    LINPTR  *tp;

    if ( (now_line + MAX_Y) > max_line ||
	 now_ptr == NULL || now_ptr->next == NULL )
	return;

    now_line++;
    old_line++;
    tp = now_ptr = now_ptr->next;
    for ( i = 1 ; tp != NULL && i < MAX_Y ; i++ )
	tp = tp->next;

    MOS_disp(OFF);
    putstr((tp == NULL ? "":tp->buf),PAGE,(MAX_Y*16+now_ofs+slow_ofs)&511);
    slow_ofs += 16;
    pas_flg = TRUE;
    scrool_bar_disp();
    MOS_disp(ON);
}
static void	FILE_one_down(void)
{
    if ( now_ptr == NULL || now_ptr->back == NULL )
	return;

    now_line--;
    old_line--;
    now_ptr = now_ptr->back;

    MOS_disp(OFF);
    putstr(now_ptr->buf,PAGE,(now_ofs+slow_ofs-16)&511);
    slow_ofs -= 16;
    pas_flg = TRUE;
    scrool_bar_disp();
    MOS_disp(ON);
}
static void	OFS_cont(void)
{
    int     n;

    if ( slow_ofs > 0 ) {
	n = (slow_ofs > scr_speed ? scr_speed:slow_ofs);
	now_ofs += n; now_ofs &= 511;
	DSP_offset(1,0,(now_ofs - SCRN_Y)&511);
	if ( (slow_ofs -= n) <= 0 && pas_flg != FALSE )
	    FILE_one_up();

    } else if ( slow_ofs < 0 ) {
	n = (-slow_ofs > scr_speed ? scr_speed:-slow_ofs);
	now_ofs -= n; now_ofs &= 511;
	DSP_offset(1,0,(now_ofs - SCRN_Y)&511);
	if ( (slow_ofs += n) >= 0 && pas_flg != FALSE )
	    FILE_one_down();
    }
}
void	FILE_irq(void)
{
    int     i,rc,sw,x,y,sx,sy;

    if ( top_ptr == NULL )
	return;

    if ( tick_timer >= tik_speed ) {
	tick_timer = 0;
        OFS_cont();
    }

    MOS_rdpos(&sw,&x,&y);
    if ( sw == 0 )
	return;

    rc = FALSE;

    if ( y >= SCRN_Y1 && y <= SCRN_Y2 ) {
	DSP_mos(1);
	do {
	    MOS_rdpos(&sw,&sx,&sy);

	    if ( cut_mode != FALSE && y >= SCRN_Y )
		rc = CLIP_box(sw == 1 ? 0:1,
			      x / 8,(y - SCRN_Y) / 16,(sx - x) / 8);

	    if ( rc == FALSE ) {
	        if ( (i = (sy - y) / 4) < 0 ) {
		    i = (y - sy) / 4;
		    scr_speed = ((tik_speed = 16 - i) < 0 ? 16:1);
	            if ( slow_ofs <= 0 )
		        FILE_one_up();
	        } else if ( i > 0 ) {
		    scr_speed = ((tik_speed = 16 - i) < 0 ? 16:1);
	            if ( slow_ofs >= 0 )
	    	        FILE_one_down();
	        } else
		    pas_flg = FALSE;
	    }

	    if ( tick_timer >= tik_speed ) {
		tick_timer = 0;
	        OFS_cont();
	    }
	} while ( sw != 0 );
	DSP_mos(0);

    } else if ( x >= BAR_X1 && x <= BAR_X2 &&
	 y >= BAR_Y1 && y <= BAR_Y2 ) {
	DSP_mos(1);
	MOS_horizon(BAR_X1,BAR_X2);
	MOS_vertical(BAR_Y1,BAR_Y2-8);
	do {
	    FILE_disp((x - BAR_X1) * max_line / BAR_SIZ);
	    MOS_rdpos(&sw,&x,&y);
	} while ( sw != 0 );
	MOS_horizon(0,632);
	MOS_vertical(0,470);
	DSP_mos(0);
    }
}
/****************************
static int	LPT_putc(char ch,FILE *fp)
{
    for ( ; ; ) {
	putc(ch,fp);
	if ( !ferror(fp) )
	    break;
	if ( pause("プリンタ出力にエラ−が発生しました！") == ERR )
	    return ERR;
	clearerr(fp);
    }
    return FALSE;
}
void	FILE_lpt(void)
{
    int     n,ln;
    LINPTR  *lp;
    FILE    *fp;
    char    *p;

    if ( top_ptr == NULL )
	return;

    if ( yesno("表示している文書をプリンタに出力しますか？") == ERR )
	return;

    if ( (fp = fopen("PRN","w")) == NULL ) {
	kakunin("プリンタ出力がオ−プン出来ません");
	return;
    }

    BREAK_open("プリンタに出力しています ちょっと待ってね");

    n = ln = 0;
    for ( lp = top_ptr ; lp != NULL ; lp = lp->next ) {
	for ( p = lp->buf ; *p != '\0' ; p++ ) {
	    if ( LPT_putc(*p,fp) )
		goto ENDOF;
	}
	if ( LPT_putc('\r',fp) || LPT_putc('\n',fp) )
	    goto ENDOF;
	if ( ++ln >= LPT_LINE ) {
	    if ( LPT_putc('\x0C',fp) )
		goto ENDOF;
	    ln = 0;
	}
	if ( BREAK_chk(max_line,++n) )
	    break;
    }
    if ( ln > 0 )
	LPT_putc('\x0C',fp);

ENDOF:
    fclose(fp);
    BREAK_close();
}
*****************************************/

void	FILE_lpt(void)
{
    int     n;
    LINPTR  *lp;

    if ( top_ptr == NULL )
	return;

    if ( yesno("表示している文書をプリンタに出力しますか？") == ERR )
	return;

    if ( LPT_open() == ERR )
	return;

    BREAK_open("プリンタに出力しています ちょっと待ってね");

    n = 0;
    for ( lp = top_ptr ; lp != NULL ; lp = lp->next ) {
	if ( PRN_puts(lp->buf) )
	    goto ENDOF;
	if ( BREAK_chk(max_line,++n) )
	    break;
    }
    PRN_close();

ENDOF:
    BREAK_close();
}

int	iskan(char *p)
{
    if ( iskanji(*p) && iskanji2(*(p+1)) )
	return TRUE;
    else
	return FALSE;
}
int	kan_pos(char *p,int n)
{
    int     i;

    for ( i = n ; i > 0 ; ) {
	if ( *p == '\0' ) {
	    return (n - i);

	} else if ( iskan(p) ) {
	    i -= 2;
	    p += 2;

	} else {
	    i--;
	    p++;
	}
    }
    return (n + i);
}

int	input(int x,int y,int max,char *str)
{
    int     i,n,ch,cd;
    int     ofs=0,len=0,pos=0;
    BLOCK   *sp;
    char    *p;
    char    tmp[128];

    INKEY_start();
    pos = len = strlen(str);

    memset(tmp,' ',max);
    tmp[max] = '\0';
    gputs(x,y,CHR_COL,WIND_COL,tmp);

    for ( ch = 0 ; ; ) {
	ofs = 0;
	n = pos;
	while ( n >= (max - 4) ) {
	    ofs += (max / 2);
	    ofs = kan_pos(str,ofs);
	    n = pos - ofs;
	}

	if ( (i = len - ofs) >= max )
	    i = kan_pos(str,ofs+max) - ofs;

	strncpy(tmp,&(str[ofs]),i);
	tmp[i] = '\0';

        sp = DSP_push_vram(x,y,x+(i+3)*8,y+15);
        gputs(x,y,CHR_COL,WIND_COL,tmp);
	DSP_box(x+n*8,y+14,x+n*8+7,y+15,13,M_XOR);

	cur_x = x + n * 8;
	cur_y = y;

	while ( (ch = getch()) == EOF );

	do {

	    if ( ch == 0x08 && pos > 0 ) {
		pos = kan_pos(str,pos-1);
		p = &(str[pos]);
		n = (iskan(p) ? 2:1);
		strcpy(p,p+n);
		len -= n;

	    } else if ( ch == 0x7F ) {
		if ( pos < len ) {
		    p = &(str[pos]);
		    n = (iskan(p) ? 2:1);
		    strcpy(p,p+n);
		    len -= n;
		}

	    } else if ( ch == 0x1C ) {
		if ( pos < len )
		    pos += (iskan(&(str[pos])) ? 2:1);

	    } else if ( ch == 0x1D ) {
		if ( pos > 0 )
		    pos = kan_pos(str,pos-1);

	    } else if ( ch >= ' ' && len < 80 ) {
		if ( pos < len ) {
		    p = &(str[len]);
		    for ( i = len - pos ; i > 0 ; i--,p-- )
			*p = *(p-1);
		}
		str[pos++] = ch;
		len++;

	    } else if ( ch == 0x0D ) {
		cd = FALSE;
		goto ENDOF;
	    } else if ( ch == 0x1B ) {
		cd = ERR;
		goto ENDOF;
	    }

	} while ( (ch = getch()) != EOF );

        DSP_pop_vram(sp);
    }

ENDOF:
    DSP_pop_vram(sp);
    str[len] = '\0';
    INKEY_end();
    if ( (i = len) >= max )
	 i = kan_pos(str,max);
    strncpy(tmp,&(str[ofs]),i);
    tmp[i] = '\0';
    gputs(x,y,CHR_COL,WIND_COL,tmp);

    return cd;
}
int	CLIP_box(box,cx,cy,len)
int	box,cx,cy,len;
{
    int     i,n;
    int     cut_x1,cut_y1,cut_x2,cut_y2;
    LINPTR  *tp;

    tp = now_ptr;
    for ( i = 0 ; tp != NULL && i < cy ; i++ )
	    tp = tp->next;

    if ( tp == NULL )
	return FALSE;

    for ( i = 0 ; tp->buf[i] != '\0' && i < cx ; i++ ) {
	if ( iskan(&(tp->buf[i])) ) {
	    if ( (i + 1) >= cx )
		break;
	    i++;
	}
    }
    cx = i;

    for ( n = 0 ; tp->buf[i] != '\0' && n < len ; ) {
	if ( iskan(&(tp->buf[i])) ) {
	    cut_buf[box][n++] = tp->buf[i++];
	    cut_buf[box][n++] = tp->buf[i++];
	} else {
	    cut_buf[box][n++] = tp->buf[i++];
	}
    }
    cut_buf[box][n] = '\0';

    if ( (len = n) == 0 )
	return FALSE;

    MOS_disp(OFF);
    DSP_page(1);
    cut_x1 = cx * 8;
    cut_y1 = (cy * 16 + now_ofs + slow_ofs) & 511;
    cut_x2 = (cx + len) * 8 - 1;
    cut_y2 = (cy * 16 + 15 + now_ofs + slow_ofs) & 511;
    DSP_vsync();
    DSP_box(cut_x1,cut_y1,cut_x2,cut_y2,8,M_XOR);
    DSP_vsync();
    DSP_box(cut_x1,cut_y1,cut_x2,cut_y2,8,M_XOR);
    DSP_page(0);
    MOS_disp(ON);

    return TRUE;
}
/********************************************************************

	COPY Funcsion

*********************************************************************/

static int	dir_make(char *file)
{
    char    *p;

    if ( (p = strchr(file,'\\')) != NULL ) {
	*p = '\0';
	if ( chdir(file) ) {
	    if ( mkdir(file) ) {
		kakunin("ディレクトリの作成に失敗しました");
		return ERR;
	    } else if ( chdir(file) ) {
		kakunin("ディレクトリの移動に失敗しました");
		return ERR;
	    }
	}
	*p = '\\';
	dir_make(p+1);
	chdir("..");
    }
    return FALSE;
}
static int	copy(char *src,char *dis)
{
    int     cd,i,n;
    long    fs;
    FILE    *ifp,*ofp;
    char    tmp[4096];

    if ( (ifp = fopen(dis,"rb")) != NULL ) {
	fclose(ifp);
	if ( yesno("%sが存在しますｺﾋﾟ-を行いますか？",dis) == ERR )
	    return TRUE;
    }

    if ( dir_make(dis) == ERR )
	return ERR;

    if ( (ifp = fopen(src,"rb")) == NULL ) {
	kakunin("%sﾌｧｲﾙがオ−プンできません",src);
	return ERR;
    }

    if ( (ofp = fopen(dis,"wb")) == NULL ) {
	fclose(ifp);
	kakunin("%sﾌｧｲﾙがオ−プンできません",dis);
	return ERR;
    }

    cd = FALSE;
    n = 0;
    fseek(ifp,0L,SEEK_END);
    fs = ftell(ifp);
    rewind(ifp);

    BREAK_open("只今%sをコピ−しています",dis);
    while ( (i = fread(tmp,1,4096,ifp)) > 0 ) {
	fwrite(tmp,1,i,ofp);
	n += i;
	if ( ferror(ifp) || ferror(ofp) ) {
	    kakunin("ファイルコピ−にエラ−が発生しました");
	    cd = ERR;
	    break;
	}
	if ( BREAK_chk(fs,n) ) {
	    cd = ERR;
	    break;
	}
    }
    fclose(ifp);
    fclose(ofp);
    if ( cd == ERR )
	remove(dis);
    BREAK_close();

    return cd;
}
static	int	cmds_copy(char *home,char *src,char *dis)
{
    int     n;
    int     cd;
    int     wd=FALSE;
    DIR     *dirp;
    DIRECT  *dp;
    char    *p;
    char    tmp[128];
    char    dmy[128];

    if ( src == NULL || *src == '\0' )
	src = "*.*";

    if ( src[1] != ':' && home != NULL ) {
	strcpy(tmp,home);
	joint_path(tmp,src);
    } else
	strcpy(tmp,src);

    for ( p = tmp ; *p != '\0' ; p++ );

    if ( strchr(tmp,'*') != NULL || strchr(tmp,'?') )
	wd = TRUE;
    else if ( (p != tmp && *(p-1) == '\\') || isdir(tmp) ) {
	joint_path(tmp,"*.*");
	wd = TRUE;
    }

    DSP_mos(2);
    dirp = opendir(tmp);
    DSP_mos(0);

    if ( dirp == NULL ) {
	kakunin("%sファイルが見当たりません",tmp);
	return ERR;
    }

    if ( (src = strrchr(tmp,'\\')) != NULL ||
	 (src = strrchr(tmp,':')) != NULL )
	src++;
    else
	src = tmp;

    if ( dis == NULL )
	dis = "";

    strcpy(dmy,dis);

    for ( n = 0 ; dmy[n] != '\0' ; n++ );
    if ( n == 0 || dmy[n-1] == '\\' || dmy[n-1] == ':' )
	 wd = TRUE;

    if ( wd != FALSE ) {
	for ( n = 0 ; dmy[n] != '\0' ; n++ );
	if ( n > 0 && dmy[n-1] != '\\' && dmy[n-1] != ':' )
	    strcat(dmy,"\\");
	dis = dmy;
	while ( *dis != '\0' ) dis++;
    }

    while ( (dp = readdir(dirp)) != NULL ) {
	if ( !IS_DIR(dp) ) {

	    strcpy(src,dp->d_name);

	    if ( wd != FALSE )
		strcpy(dis,dp->d_name);

	    while ( (cd = copy(tmp,dmy)) == ERR ) {
		if ( pause("コピ−を続行しますか？") == ERR )
		    goto ENDOF;
	    }
	}
    }

ENDOF:
    closedir(dirp);
    return (cd == ERR ? ERR:FALSE);
}
static	int	cmds_rename(char *src,char *dis)
{
    if ( src[0] != '\0' && src[1] == ':' ) {
	kakunin("絶対パスでのファイル名変更はできません");
	return ERR;
    }

    if ( rename(src,dis) ) {
	kakunin("ファイル名の変更ができませんでした");
	return ERR;
    }
    return FALSE;
}
static	int	cmds_mkdir(char *dir)
{
    if ( dir[0] != '\0' && dir[1] == ':' ) {
	kakunin("絶対パスでのディレクトリ作成はできません");
	return ERR;
    }

    if ( mkdir(dir) ) {
	kakunin("ディレクトリの作成ができませんでした");
	return ERR;
    }
    return FALSE;
}
static	int	cmds_chdir(char *dir)
{
    if ( dir[0] != '\0' && dir[1] == ':' ) {
	kakunin("絶対パスでのディレクトリ移動はできません");
	return ERR;
    }

    if ( chdir(dir) ) {
	kakunin("ディレクトリの移動ができませんでした");
	return ERR;
    }
    return FALSE;
}
static	int	cmdstr(char *src,char *ptn)
{
    while ( *ptn != '\0' ) {
	if ( toupper(*src) != *ptn )
	    return FALSE;
	src++;
	ptn++;
    }
    if ( *src == '\0' || isspace(*src) )
	return TRUE;
    else
	return FALSE;
}

#define	ST_EOF		0
#define	ST_ELSE		1
#define	ST_ENDIF	2

static	char	cmds_dmy[BUFSIZ];
static	char	cmds_home[BUFSIZ];

static	int	cmds_line(LINPTR **fp,int rc)
{
    int     n;
    char    *p;
    char    *s;
    char    *r;

    while ( (*fp)->next != NULL ) {
	(*fp) = (*fp)->next;
	p = (*fp)->buf;

	while ( isspace(*p) ) p++;

	if ( *p == '\0' || *p == '#' )
	    continue;

	if ( cmdstr(p,"IF") ) {
	    if ( rc == FALSE ) {
		while ( (n = cmds_line(fp,FALSE)) == ST_ELSE );
		if ( n == ST_EOF )
		    break;

		continue;
	    }

	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    if ( yesno2(p) == ERR ) {	/* else */
		if ( (n = cmds_line(fp,FALSE)) == ST_ELSE )
		   n = cmds_line(fp,TRUE);

	    } else {			/* then */
		if ( (n = cmds_line(fp,TRUE)) == ST_ELSE )
		   n = cmds_line(fp,FALSE);
	    }
	    if ( n == ST_EOF )
		break;

	    continue;

	} else if ( cmdstr(p,"ELSE") ) {
	    return ST_ELSE;

	} else if ( cmdstr(p,"ENDIF") ) {
	    return ST_ENDIF;
	}

	if ( rc == FALSE )
	    continue;

	if ( cmdstr(p,"COPY") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    s = p;
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    if ( *p != '\0' ) *(p++) = '\0';
	    while ( isspace(*p) ) p++;
	    r = p;
	    while ( !isspace(*r) && *r != '\0' ) r++;
	    *r = '\0';
	    if ( cmds_copy(cmds_home,s,p) )
		break;

	} else if ( cmdstr(p,"RENAME") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    s = p;
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    if ( *p != '\0' ) *(p++) = '\0';
	    while ( isspace(*p) ) p++;
	    r = p;
	    while ( !isspace(*r) && *r != '\0' ) r++;
	    *r = '\0';
	    if ( cmds_rename(s,p) )
		break;

	} else if ( cmdstr(p,"MKDIR") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    r = p;
	    while ( !isspace(*r) && *r != '\0' ) r++;
	    *r = '\0';
	    if ( cmds_mkdir(p) )
		break;

	} else if ( cmdstr(p,"CHDIR") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    r = p;
	    while ( !isspace(*r) && *r != '\0' ) r++;
	    *r = '\0';
	    if ( cmds_chdir(p) )
		break;

	} else if ( cmdstr(p,"PAUSE") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    if ( pause(p) == ERR )
		break;

	} else if ( cmdstr(p,"INST") ) {
	    while ( !isspace(*p) && *p != '\0' ) p++;
	    while ( isspace(*p) ) p++;
	    r = p;
	    while ( !isspace(*r) && *r != '\0' ) r++;
	    *r = '\0';
	    strcpy(cmds_dmy,cmds_home);
	    joint_path(cmds_dmy,p);
	    if ( cmds_file(cmds_dmy) )
		break;

	} else if ( cmdstr(p,"EXIT") ) {
	    break;

	}
    }

    return ST_EOF;
}
static	int	cmds_file(char *file)
{
    int     n;
    LINPTR  tp;
    LINPTR  *fp;
    char    *p;
    char    home[BUFSIZ];

    n = max_line;
    if ( (tp.next = read_file(file)) == NULL ) {
	kakunin("'%s'コマンドが見当たりません",file);
	return ERR;
    }
    max_line = n;

    strcpy(home,cmds_home);
    strcpy(cmds_home,file);
    if ( (p = strrchr(cmds_home,'\\')) != NULL )
	*p = '\0';

    fp = &tp;
    cmds_line(&fp,TRUE);

    strcpy(cmds_home,home);
    free_file(tp.next);
    return FALSE;
}
static int	wcopy(char *wild)
{
    int     cd;
    DIR     *dirp;
    DIRECT  *dp;
    char    *p;
    char    *src,*dis;
    char    tmp[128];

    if ( (p = strrchr(wild,'\\')) == NULL )
	p = wild;

    if ( (p = strrchr(p,'.')) != NULL && strcmp(p,".QQQ") == 0 )
	return cmds_file(wild);

    DSP_mos(2);
    dirp = opendir(wild);
    DSP_mos(0);

    if ( dirp == NULL )
	return TRUE;

    strcpy(tmp,wild);
    if ( (p = strrchr(tmp,'\\')) != NULL )
	p++;
    else
	p = tmp;

    while ( (dp = readdir(dirp)) != NULL ) {
	if ( !IS_DIR(dp) ) {

	    strcpy(p,dp->d_name);
	    src = tmp;
	    dis = dp->d_name;

	    while ( (cd = copy(src,dis)) == ERR ) {
		if ( yesno("コピ−を続行しますか？") == ERR )
		    goto ENDOF;
	    }
	}
    }

ENDOF:
    closedir(dirp);
    return cd;
}

#define	CHDIR_X1	(11*8-4)
#define	CHDIR_Y1	150
#define	CHDIR_X2	(68*8+3)
#define	CHDIR_Y2	340

#define	CHDIR_MSG_X	((CHDIR_X1+CHDIR_X2)/2)
#define	CHDIR_MSG_Y	(CHDIR_Y1+30)

#define	CHDIR_TTL_X	(CHDIR_X1+3*8)

#define	CHDIR_BACK_X	(CHDIR_X1+17*8)
#define	CHDIR_BACK_Y	(CHDIR_Y1+70)

#define	CHDIR_BACK_X1	(CHDIR_BACK_X-4)
#define	CHDIR_BACK_Y1	(CHDIR_BACK_Y-9)
#define	CHDIR_BACK_X2	(CHDIR_BACK_X+2*8+4)
#define	CHDIR_BACK_Y2	(CHDIR_BACK_Y1+33)

#define	CHDIR_DRIV_X	(CHDIR_X1+20*8)
#define	CHDIR_DRIV_Y	(CHDIR_Y1+61)

#define	CHDIR_DRIV_X1	(CHDIR_DRIV_X)
#define	CHDIR_DRIV_Y1	(CHDIR_DRIV_Y)
#define	CHDIR_DRIV_X2	(CHDIR_DRIV_X+33)
#define	CHDIR_DRIV_Y2	(CHDIR_DRIV_Y+33)

#define	CHDIR_NEXT_X	(CHDIR_X1+25*8+2)
#define	CHDIR_NEXT_Y	(CHDIR_Y1+70)

#define	CHDIR_NEXT_X1	(CHDIR_NEXT_X-4)
#define	CHDIR_NEXT_Y1	(CHDIR_NEXT_Y-9)
#define	CHDIR_NEXT_X2	(CHDIR_NEXT_X+2*8+4)
#define	CHDIR_NEXT_Y2	(CHDIR_NEXT_Y1+33)

#define	CHDIR_DIR_X	(CHDIR_X1+17*8)
#define	CHDIR_DIR_Y	(CHDIR_Y1+110)

#define	CHDIR_YES_X	((CHDIR_X1+CHDIR_X2)/2-(10*8))
#define	CHDIR_YES_Y	(CHDIR_Y1+150)

#define	CHDIR_NO_X	((CHDIR_X1+CHDIR_X2)/2+(2*8))
#define	CHDIR_NO_Y	(CHDIR_Y1+150)

void	COPY_all(int argc,char *argv[])
{
    int     now,fg;
    int     cd,sw,bx,by;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    char    *p,*s;
    char    tmp[256];

    if ( yesno("プログラムのコピ−を行いますか？") == ERR )
	return;

    MOS_disp(OFF);
    sp = DSP_push_vram(CHDIR_X1,CHDIR_Y1,CHDIR_X2,CHDIR_Y2);
    DSP_opbox(CHDIR_X1,CHDIR_Y1,CHDIR_X2,CHDIR_Y2);
    DSP_wbox(CHDIR_X1,CHDIR_Y1,CHDIR_X2,CHDIR_Y2,LINE_COL,FILD_COL,M_PSET);
    strcpy(tmp,"コピ−先のドライブなどを指定してください");
    gputs(CHDIR_MSG_X-strlen(tmp)*4,CHDIR_MSG_Y,CHR_COL,FILD_COL,tmp);
    gputs(CHDIR_TTL_X,CHDIR_BACK_Y,CHR_COL,FILD_COL,"ドライブ");
    gputs(CHDIR_TTL_X,CHDIR_DIR_Y,CHR_COL,FILD_COL,"ディレクトリ");

    now = getdrv();
    DSP_wbox(CHDIR_BACK_X1,CHDIR_BACK_Y1,
	     CHDIR_BACK_X2,CHDIR_BACK_Y2,LINE_COL,WIND_COL,M_PSET);
    gputs(CHDIR_BACK_X,CHDIR_BACK_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_set(ep,1,CHDIR_BACK_X1,CHDIR_BACK_Y1,
		      CHDIR_BACK_X2,CHDIR_BACK_Y2,EVT_proc);

    ep = EVT_set(ep,2,CHDIR_DRIV_X1,CHDIR_DRIV_Y1,
		      CHDIR_DRIV_X2,CHDIR_DRIV_Y2,EVT_proc);

    DSP_wbox(CHDIR_NEXT_X1,CHDIR_NEXT_Y1,
	     CHDIR_NEXT_X2,CHDIR_NEXT_Y2,LINE_COL,WIND_COL,M_PSET);
    gputs(CHDIR_NEXT_X,CHDIR_NEXT_Y,CHR_COL,WIND_COL,"＞");
    ep = EVT_set(ep,3,CHDIR_NEXT_X1,CHDIR_NEXT_Y1,
		      CHDIR_NEXT_X2,CHDIR_NEXT_Y2,EVT_proc);

    sprintf(tmp,"%-34.34s","？");
    ep = EVT_sw(ep,4,CHDIR_DIR_X,CHDIR_DIR_Y,CHR_COL,WIND_COL,tmp);
    ep = EVT_sw(ep,5,CHDIR_YES_X,CHDIR_YES_Y,CHR_COL,WIND_COL," 実  行");
    ep = EVT_sw(ep,6,CHDIR_NO_X,CHDIR_NO_Y,CHR_COL,WIND_COL," 取  消 ");
    ICON_disp(CHDIR_DRIV_X,CHDIR_DRIV_Y,now);

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((CHDIR_X1+CHDIR_X2)/2,(CHDIR_Y1+CHDIR_Y2)/2);
    MOS_disp(ON);

    tmp[0] = '\0';
    for ( cd = FALSE ; cd == FALSE ; ) {
	switch(EVT_wait(ep)) {
	case 1:
	    do {
		if ( --now < 0 ) now = 16;
	    } while ( drv_tbl[now] == IS_NON );
	    MOS_disp(OFF);
	    ICON_disp(CHDIR_DRIV_X,CHDIR_DRIV_Y,now);
	    tmp[0] = '\0';
	    gprintf(CHDIR_DIR_X,CHDIR_DIR_Y,CHR_COL,WIND_COL,"%-34.34s","？");
	    MOS_disp(ON);
	    break;

	case 2:
	    DSP_mos(2);
	    chdrv(now);
	    if ( getdir(tmp) )
		tmp[0] = 0;
	    DSP_mos(0);
	    MOS_disp(OFF);
	    gprintf(CHDIR_DIR_X,CHDIR_DIR_Y,CHR_COL,WIND_COL,"%-34.34s",
					tmp[0] == '\0' ? "？":tmp);
	    MOS_disp(ON);
	    break;

	case 3:
	    do {
		if ( ++now >= 17 ) now = 0;
	    } while ( drv_tbl[now] == IS_NON );
	    MOS_disp(OFF);
	    ICON_disp(CHDIR_DRIV_X,CHDIR_DRIV_Y,now);
	    tmp[0] = '\0';
	    gprintf(CHDIR_DIR_X,CHDIR_DIR_Y,CHR_COL,WIND_COL,"%-34.34s","？");
	    MOS_disp(ON);
	    break;

	case 4:
	    MOS_disp(OFF);
	    input(CHDIR_DIR_X,CHDIR_DIR_Y,33,tmp);
	    gprintf(CHDIR_DIR_X,CHDIR_DIR_Y,CHR_COL,WIND_COL,"%-34.34s",
					tmp[0] == '\0' ? "？":tmp);
	    MOS_disp(ON);
	    break;

	case 5: cd = TRUE; break;
	case 6: cd = ERR;  break;
	}
    }

    EVT_free(ep);
    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(CHDIR_X1,CHDIR_Y1,CHDIR_X2,CHDIR_Y2);
    MOS_setpos(bx,by);
    DSP_mos(2);
    MOS_disp(ON);

    if ( cd == TRUE ) {
	if ( chdrv(now) ) {
	    kakunin("ドライブが異常なので処理を中断します");
	    cd = ERR;
	    goto ENDOF;
	}
	p = tmp;
	if ( *p == '\\' ) {
	    chdir("\\");
	    p++;
	}
	while ( *p != '\0' ) {
	    if ( (s = strchr(p,'\\')) == NULL ) {
		for ( s = p ; *s != '\0' ; s++ );
		fg = TRUE;
	    } else
		fg = FALSE;

	    *s = '\0';

	    if ( *p == '\0' )
		break;

	    if ( chdir(p) ) {
		if ( yesno("%sディレクトリを作成しますか？",p) == ERR ) {
		    cd = ERR;
		    goto ENDOF;
		}
		if ( mkdir(p) ) {
		    kakunin("ディレクトリの作成に失敗しました");
		    cd = ERR;
		    goto ENDOF;
		} else if ( chdir(p) ) {
		    kakunin("ディレクトリの移動に失敗しました");
		    cd = ERR;
		    goto ENDOF;
		}
	    }

	    if ( fg != FALSE )
		break;
	    *(s++) = '\\';
	    p = s;
	}

	while ( argc-- > 0 && wcopy(*(argv++)) != ERR );

    }

ENDOF:

    DSP_mos(0);
}

/*************************************************************
01234567890123456789012345678901234567890123456789012345678901234567890123456789                01234567890123456789012345678901234567890123456
                +---------------------------------------------+
0               |                FILE SELECTER            |×||
1               |+---++---++---++---++---++---++---++---++---+|
2               || A || B || C || D || E || F || G || H || I ||
3               |+---++---++---++---++---++---++---++---++---+|
4               |+---++---++---++---++---++---++---++---++---+|
5               || J || K || L || M || N || O || P || Q || R ||
6               |+---++---++---++---++---++---++---++---++---+|
7               |******************************************** |
8               |xxxxxxxxxx xxx|xxxxxxxxxx xxx|xxxxxxxxxx xxx |
9               |xxxxxxxxxx xxx|xxxxxxxxxx xxx|xxxxxxxxxx xxx |
10              |xxxxxxxxxx xxx|xxxxxxxxxx xxx|xxxxxxxxxx xxx |
11              |xxxxxxxxxx xxx|xxxxxxxxxx xxx|xxxxxxxxxx xxx |
12              |xxxxxxxxxx xxx|xxxxxxxxxx xxx|xxxxxxxxxx xxx |
13              |ooooooooooooooooooooooooooooooooooooo|＜||＞||
14              +---------------------------------------------+
**************************************************************/

#define	FSEL_X1		(16*8)
#define	FSEL_Y1		(240-8*20)
#define	FSEL_X2		(62*8)
#define	FSEL_Y2		(FSEL_Y1+264)

#define	FSEL_MSG_X	(FSEL_X1+17*8)
#define	FSEL_MSG_Y	(FSEL_Y1+4)

#define	FSEL_EXIT_X	(FSEL_X1+43*8-2)
#define	FSEL_EXIT_Y	(FSEL_Y1+4)

#define	FSEL_DRIV_X	(FSEL_X1+1*8)
#define	FSEL_DRIV_Y	(FSEL_Y1+24)

#define	FSEL_DIR_X	(FSEL_X1+1*8)
#define	FSEL_DIR_Y	(FSEL_Y1+103)

#define	FSEL_FILE_X	(FSEL_X1+1*8)
#define	FSEL_FILE_Y	(FSEL_Y1+124)

#define	FSEL_BACK_X	((FSEL_X1+FSEL_X2)/2-4*8)
#define	FSEL_BACK_Y	(FSEL_Y1+240)

#define	FSEL_NEXT_X	((FSEL_X1+FSEL_X2)/2+2*8)
#define	FSEL_NEXT_Y	(FSEL_Y1+240)

#define	FSEL_DPOS_X1(n)	(FSEL_DRIV_X+((n)%9)*40)
#define	FSEL_DPOS_Y1(n)	(FSEL_DRIV_Y+((n)/9)*40)
#define	FSEL_DPOS_X2(n)	(FSEL_DRIV_X+((n)%9)*40+33)
#define	FSEL_DPOS_Y2(n)	(FSEL_DRIV_Y+((n)/9)*40+33)

#define	FSEL_FPOS_X1(n)	(FSEL_FILE_X+((n)/5)*15*8-4)
#define	FSEL_FPOS_Y1(n)	(FSEL_FILE_Y+((n)%5)*22)
#define	FSEL_FPOS_X2(n)	(FSEL_FILE_X+((n)/5)*15*8+15*8-6)
#define	FSEL_FPOS_Y2(n)	(FSEL_FILE_Y+((n)%5)*22+19)

char	*formname(name)
char	*name;
{
    int     i;
    char    *p;
    static char tmp[16];

    if ( strcmp(name,"..") == 0 || (p = strchr(name,'.')) == NULL )
        for ( p = name ; *p != '\0' ; p++ );

    for ( i = 0 ; name < p && i < 8 ; i++ )
	tmp[i] = *(name++);

    for ( ; i < 11 ; i++ )
	tmp[i] = ' ';

    if ( *p == '.' ) p++;

    while ( *p != '\0' )
	tmp[i++] = *(p++);

    for ( ; i < 14 ; i++ )
	tmp[i] = ' ';

    tmp[i] = '\0';
    return tmp;
}
char	*FILE_select(void)
{
    int     i,n,cd;
    int     sw,bx,by;
    int     drv_old,drv_now;
    int     pos_old,pos_now;
    int     dir_flg,dir_max;
    BLOCK   *sp;
    EVENT   *ep=NULL;
    DIR     *dirp;
    DIRECT  *dp;
    DIRECT  *file_ptr[15];
    char    drv_no[17];
    static char tmp[128];

    MOS_disp(OFF);
    sp = DSP_push_vram(FSEL_X1,FSEL_Y1,FSEL_X2,FSEL_Y2);
    DSP_opbox(FSEL_X1,FSEL_Y1,FSEL_X2,FSEL_Y2);
    DSP_wbox(FSEL_X1,FSEL_Y1,FSEL_X2,FSEL_Y2,LINE_COL,FILD_COL,M_PSET);
    gputs(FSEL_MSG_X,FSEL_MSG_Y,CHR_COL,FILD_COL,"FILE SELECTER");

    ep = EVT_sw(ep,0,FSEL_EXIT_X,FSEL_EXIT_Y,CHR_COL,WIND_COL,"×");
    ep = EVT_sw(ep,1,FSEL_BACK_X,FSEL_BACK_Y,CHR_COL,WIND_COL,"△");
    ep = EVT_sw(ep,2,FSEL_NEXT_X,FSEL_NEXT_Y,CHR_COL,WIND_COL,"▽");

    for ( i = n = 0 ; i < 17 ; i++ ) {
	if ( drv_tbl[i] != IS_NON ) {
	    ICON_disp(FSEL_DPOS_X1(n),FSEL_DPOS_Y1(n),i);
	    ep = EVT_set(ep,i+100,
			FSEL_DPOS_X1(n),FSEL_DPOS_Y1(n),
		        FSEL_DPOS_X2(n),FSEL_DPOS_Y2(n),EVT_proc);
	    drv_no[i] = n;
	    n++;
	} else
	    drv_no[i] = 17;
    }

    for ( i = 0 ; i < 15 ; i++ ) {
	ep = EVT_set(ep,i+200,
		FSEL_FPOS_X1(i),FSEL_FPOS_Y1(i),
	        FSEL_FPOS_X2(i),FSEL_FPOS_Y2(i),EVT_proc);
	DSP_wbox(FSEL_FPOS_X1(i),FSEL_FPOS_Y1(i),
	         FSEL_FPOS_X2(i),FSEL_FPOS_Y2(i),LINE_COL,WIND_COL,M_PSET);
    }

    DSP_wbox(FSEL_DIR_X-4,FSEL_DIR_Y-2,
	     FSEL_DIR_X+(44*8)+2,FSEL_DIR_Y+17,LINE_COL,WIND_COL,M_PSET);

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((FSEL_X1+FSEL_X2)/2,(FSEL_Y1+FSEL_Y2)/2);
    MOS_disp(ON);

    drv_now = getdrv();
    drv_old = ERR;
    dir_flg = TRUE;
    dirp = NULL;
    pos_old = ERR;
    pos_now = 0;

    for ( cd = FALSE ; cd == FALSE ; ) {

	if ( drv_old != drv_now ) {
	    MOS_disp(OFF);
	    if ( drv_old != ERR )
		DSP_box(FSEL_DPOS_X1(drv_no[drv_old]),
			FSEL_DPOS_Y1(drv_no[drv_old]),
			FSEL_DPOS_X2(drv_no[drv_old]),
			FSEL_DPOS_Y2(drv_no[drv_old]),
			11,M_XOR);

	    DSP_box(FSEL_DPOS_X1(drv_no[drv_now]),
		    FSEL_DPOS_Y1(drv_no[drv_now]),
		    FSEL_DPOS_X2(drv_no[drv_now]),
		    FSEL_DPOS_Y2(drv_no[drv_now]),
		    11,M_XOR);
	    MOS_disp(ON);

	    DSP_mos(2);
	    chdrv(drv_now);
	    DSP_mos(0);

	    drv_old = drv_now;
	    dir_flg = TRUE;
	}

	if ( dir_flg != FALSE ) {
	    DSP_mos(2);
	    getdir(tmp);

	    MOS_disp(OFF);
	    gprintf(FSEL_DIR_X,FSEL_DIR_Y,CHR_COL,WIND_COL,"%-44.44s",tmp);
	    MOS_disp(ON);

	    if ( tmp[1] != '\0' )
		strcat(tmp,"\\");
	    strcat(tmp,"*.*");
	    if ( dirp !=  NULL )
		closedir(dirp);
	    dirp = opendir(tmp);
	    dir_max = countdir(dirp);
	    pos_now = 0;
	    pos_old = ERR;
	    dir_flg = FALSE;
	    DSP_mos(0);
	}

	if ( pos_old != pos_now ) {
	    seekdir(dirp,pos_now);
	    MOS_disp(OFF);
	    for ( i = 0 ; i < 15 ; i++ ) {
		dp = readdir(dirp);
		gputs(FSEL_FPOS_X1(i)+4,FSEL_FPOS_Y1(i)+2,
			(IS_DIR(dp) ? KEY_COL:CHR_COL),WIND_COL,
			(dp != NULL ? 
				  formname(dp->d_name):"              "));
		file_ptr[i] = dp;
	    }
	    MOS_disp(ON);
	    pos_old = pos_now;
	}

	i = EVT_wait(ep);

	if ( i == 0 ) {
	    cd = ERR;

	} else if ( i == 1 ) {
	    if ( pos_now > 0 )
		pos_now -= 15;

	} else if ( i == 2 ) {
	    if ( (pos_now + 15) < dir_max )
	         pos_now += 15;

	} else if ( i >= 200 ) {
	    if ( (dp = file_ptr[i-200]) != NULL ) {
		if ( IS_DIR(dp) ) {
		    chdir(dp->d_name);
		    dir_flg = TRUE;
		} else {
		    strcpy(tmp,dp->d_name);
		    cd = TRUE;
		}
	    }

	} else if ( i >= 100 ) {
	    drv_now = i - 100;
	    dir_flg = TRUE;
	}
    }

    if ( dirp != NULL )
	closedir(dirp);

    EVT_free(ep);
    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(FSEL_X1,FSEL_Y1,FSEL_X2,FSEL_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);

    return (cd == ERR ? NULL:tmp);
}
