#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>

#ifdef	MSDOS
#include    <jctype.h>
#include    <dos.h>
#else
#include    <sys/types.h>
#include    <sys/ioctl.h>
#include    <sys/termio.h>
#include    <sys/tty.h>
#endif

#include    "defs.h"

typedef	struct	{
	char	at;
	char	ch;
	} VRAM;

static	VRAM	*vram = NULL;
static	VRAM	*dram = NULL;
static	VRAM	*sram = NULL;

static	char	tc_ent[2048];
static	char	tc_buf[2048];
static	int	R7;
static	char	*CD, *CE, *CL,
		*CM, *HO, *LL,
		*LE, *ND, *DO, *UP,
		*DC, *IC, *DL, *AL,
		*MB, *MD, *MR,
		*ME, *SA,
		*SO, *SX, *SM, *SE,
		*SF, *SR,
		*VB,
		*VI, *VE;

	int	lines_max = 0;
	int	cols_max = 0;

static	int	lines_sys = 0;
static	int	now_at = 0;
static	int	now_x = 0;
static	int	now_y = 0;
static	int	scr_ofs = 0;
static	int	cur_dsp = TRUE;
static	int	back_x, back_y;
static	int	save_flag = FALSE;

	char	*getenv();
	char	*tgetstr();
	char	*tgoto();
	void	setkey();
	void	SYSLINE();

static	struct	{
	int	code;
	char	*cap;
	} key_tab[] = {
		{ 0x8001,	"k1" },		/* PF1 */
		{ 0x8002,	"k2" },		/* PF2 */
		{ 0x8003,	"k3" },		/* PF3 */
		{ 0x8004,	"k4" },		/* PF4 */
		{ 0x8005,	"k5" },		/* PF5 */
		{ 0x8006,	"k6" },		/* PF6 */
		{ 0x8007,	"k7" },		/* PF7 */
		{ 0x8008,	"k8" },		/* PF8 */
		{ 0x8009,	"k9" },		/* PF9 */
		{ 0x800A,	"k;" },		/* PF10 */
		{ 0x800B,	"F1" },		/* PF11 */
		{ 0x800C,	"F2" },		/* PF12 */
		{ 0x800D,	"F3" },		/* PF13 */
		{ 0x800E,	"F4" },		/* PF14 */
		{ 0x800F,	"F5" },		/* PF15 */
		{ 0x8010,	"F6" },		/* PF16 */
		{ 0x8011,	"F7" },		/* PF17 */
		{ 0x8012,	"F8" },		/* PF18 */
		{ 0x8013,	"F9" },		/* PF19 */
		{ 0x8014,	"F;" },		/* PF20 */
		{ 0x001C,	"kr" },		/* RIGHT */
		{ 0x001D,	"kl" },		/* LEFT */
		{ 0x001E,	"ku" },		/* UP */
		{ 0x001F,	"kd" },		/* DOWN */
		{ 0x007F,	"kD" },		/* DEL */
		{ 0x0000,	NULL },
	};

static	int	tput_len = 0;
static	char	tput_buf[512];

static	void	tflush()
{
#ifdef	MSDOS
    char far *p;
    union REGS reg;
    struct SREGS seg;

    p = tput_buf;
    reg.h.ah = 0x1E;
    reg.x.cx = tput_len;
    seg.ds   = FP_SEG(p);
    reg.x.di = FP_OFF(p);
    int86x(0x91, &reg, &reg, &seg);
    tput_len = 0;
#else
    fflush(stdout);
#endif
}
static	void	tputc(int code)
{
#ifdef	MSDOS
    if ( tput_len >= 512 )
	tflush();
    tput_buf[tput_len++] = code;
#else
    putchar(code);
#endif
}
int	SCRNINIT(char *ent)
{
    int     n;
    char    *term;
    char    *ptr = tc_buf;
    char    *p, *s;
#ifndef	MSDOS
    struct winsize winsize;
#endif

    if ( (term = ent) == NULL && (term = getenv("TERM")) == NULL )
	return ERR;

    if ( tgetent(tc_ent, term) < 0 )
	return ERR;

#ifdef	MSDOS
    lines_max = tgetnum("li");
    cols_max  = tgetnum("co");

    if ( (p = getenv("LINES")) != NULL )
	lines_max = atoi(p);
    if ( (p = getenv("COLS")) != NULL )
	cols_max = atoi(p);
#else
    if( ioctl(1, TIOCGWINSZ, &winsize) != -1 ) {
        lines_max = winsize.ws_row;
        cols_max  = winsize.ws_col;
    } else {
        lines_max = tgetnum("li");
        cols_max  = tgetnum("co");

        if ( (p = getenv("LINES")) != NULL )
	    lines_max = atoi(p);
        if ( (p = getenv("COLUMNS")) != NULL )
	    cols_max = atoi(p);
        if ( (p = getenv("COLS")) != NULL )
            cols_max = atoi(p);
    }
#endif

    if ( lines_max <= 0 || lines_max >= 160 )
	lines_max = 24;
    if ( cols_max <= 0  || cols_max >= LINSIZ )
	cols_max = 80;

    lines_sys = lines_max - 1;
#ifndef	MSDOS
    lines_max--;
#endif

    CD = tgetstr("cd", &ptr);	/* Clear to end of display.	*/
    CE = tgetstr("ce", &ptr);	/* Clear to end of line.	*/
    CL = tgetstr("cl", &ptr);	/* Clear screen and home cursor	*/

    CM = tgetstr("cm", &ptr);	/* Screen-relative cursor motion*/

    HO = tgetstr("ho", &ptr);	/* Home cursor.			*/
    LL = tgetstr("ll", &ptr);	/* Last line, first column	*/

    LE = tgetstr("le", &ptr);	/* Move cursor left one pos.	*/
    ND = tgetstr("nd", &ptr);	/* Move cursor right one pos.	*/
    DO = tgetstr("do", &ptr);	/* Down one line.		*/
    UP = tgetstr("up", &ptr);	/* Up one line.			*/

    DC = tgetstr("dc", &ptr);	/* Delete character		*/
    IC = tgetstr("ic", &ptr);	/* Insert character		*/
    DL = tgetstr("dl", &ptr);	/* Delete line.			*/
    AL = tgetstr("al", &ptr);	/* Add new blank line.		*/

    MB = tgetstr("mb", &ptr);	/* Turn on blinking attribute.	*/
    MD = tgetstr("md", &ptr);	/* Turn on bold attribute.	*/
    MR = tgetstr("mr", &ptr);	/* Turn on reverse attibute.	*/
    ME = tgetstr("me", &ptr);	/* Turn off all attributes.	*/

    SA = tgetstr("sa", &ptr);	/* Define the video attributes.	*/
    SO = tgetstr("so", &ptr);	/* Begin standout mode.		*/
    SX = tgetstr("sx", &ptr);	/* Begin error mode.		*/
    SM = tgetstr("sm", &ptr);	/* Begin message mode.		*/
    SE = tgetstr("se", &ptr);	/* End standout mode.		*/

    SF = tgetstr("sf", &ptr);	/* Scroll text up.		*/
    SR = tgetstr("sr", &ptr);	/* Scroll text down.		*/

    VB = tgetstr("vb", &ptr);	/* Visible bell			*/

    VI = tgetstr("vi", &ptr);	/* Cursor Display Off		*/
    VE = tgetstr("ve", &ptr);	/* Cursor Display On		*/

    R7 = tgetflag("r7");	/* FMR70 Ext Kanji Code		*/

    for ( n = 0 ; key_tab[n].cap != NULL ; n++ ) {
	s = ptr;
	if ( (p = tgetstr(key_tab[n].cap, &s)) != NULL )
	    setkey(key_tab[n].code, p);
    }

    if ( CL == NULL || CM == NULL || CE == NULL )
	return ERR;

    if ( (vram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL ||
         (dram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL ||
         (sram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL )
	return ERR;

    memset(vram, 0, sizeof(VRAM) * cols_max * lines_max);
    memset(dram, 0, sizeof(VRAM) * cols_max * lines_max);

    tputs(CL, 1, tputc);
    tflush();

    cur_dsp = TRUE;

    return FALSE;
}
void	FLUSH()
{
    int n, i;
    int x, y;
    int sx = (-1);
    int sy = (-1);
    int at = 0;
    VRAM *vp, *dp;

    vp = vram;
    dp = dram;

    if ( cur_dsp == TRUE && VI != NULL )
	tputs(VI, 1, tputc);

    if ( scr_ofs > 0 && scr_ofs < (lines_max / 2) ) {
	memcpy(&(dram[0 * cols_max]),
	       &(dram[scr_ofs * cols_max]),
		sizeof(VRAM) * (lines_max - scr_ofs) * cols_max);
        memset(&(dram[(lines_max - scr_ofs) * cols_max]), 0,
		sizeof(VRAM) * scr_ofs * cols_max);

	tputs((HO != NULL ? HO : tgoto(CM, 0, 0)), 1, tputc);
	while ( scr_ofs-- > 0 )
	    tputs(DL, 1, tputc);
	if ( lines_max == lines_sys )
	    SYSLINE(NULL);

    } else if ( scr_ofs < 0 && (0 - scr_ofs) < (lines_max / 2) ) {
        for ( y = lines_max - 1 ; y >= (0 - scr_ofs) ; y-- )
	    memcpy(&(dram[y * cols_max]),
	           &(dram[(y + scr_ofs) * cols_max]), sizeof(VRAM) * cols_max);
        memset(&(dram[0 * cols_max]), 0,
		sizeof(VRAM) * (0 - scr_ofs) * cols_max);

	tputs((HO != NULL ? HO : tgoto(CM, 0, 0)), 1, tputc);
	while ( scr_ofs++ < 0 )
	    tputs(AL, 1, tputc);
	if ( lines_max == lines_sys )
	    SYSLINE(NULL);
    }
    scr_ofs = 0;

#if	1
    for ( y = 0 ; y < lines_max ; y++ ) {
	for ( x = 0 ; x < cols_max ; x++ ) {
	    if ( vp->ch != dp->ch || vp->at != dp->at ) {
		if ( (vp->at & 0x40) != 0 ) {
		    x--; vp--; dp--;
		    if ( (vp->at & 0x80) == 0 ) {
		        x++; vp++; dp++;
			vp->at &= 0xBF;
		    }
		}
		if ( sx != x || sy != y ) {
		    if ( sy == y && (sx + 5) >= x && ND != NULL ) {
			while ( sx++ < x )
			    tputs(ND, 1, tputc);
		    } else
			tputs(tgoto(CM, x, y), 1, tputc);
		    sx = x;
		    sy = y;
		}
		if ( (vp->at & 0x3F) != at ) {
		    n = vp->at & 0x3F;
		    if ( (at & 0x07) != 0 && ME != NULL ) {
			at = 0;
			tputs(ME, 1, tputc);
		    }
		    if ( (n & 0x01) != 0 && MB != NULL && ME != NULL )
			tputs(MB, 1, tputc);
		    if ( (n & 0x02) != 0 && MD != NULL && ME != NULL )
			tputs(MD, 1, tputc);
		    if ( (n & 0x04) != 0 && MR != NULL && ME != NULL )
			tputs(MR, 1, tputc);

		    if ( (n & 0x38) != (at & 0x38) ) {
			switch(n & 0x18) {
			case 0x00:
			    if ( SE != NULL )
				tputs(SE, 1, tputc);
			    break;
			case 0x08:
			    if ( SO != NULL )
				tputs(SO, 1, tputc);
			    break;
			case 0x10:
			    if ( SX != NULL )
				tputs(SX, 1, tputc);
			    break;
			case 0x18:
			    if ( SM != NULL )
				tputs(SM, 1, tputc);
			    break;
			}
		    }
		    at = n;
		}
		if ( (vp[0].at & 0x80) != 0 && (vp[1].at & 0x40) != 0 ) {
		    tputc(vp[0].ch);
		    tputc(vp[1].ch);
		    dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
		    dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
		    sx+=2;
		    x++;
		    
		} else {
		    if ( vp->ch == 0 && CE != NULL &&
				memcmp(vp, vp + 1,
				sizeof(VRAM) * (cols_max - x - 1)) == 0 ) {
			tputs(CE, 1, tputc);
			n = cols_max - x;
			memcpy(dp, vp, sizeof(VRAM) * n);
			x += n;
			vp += n;
			dp += n;
		    } else {
			n = (vp->ch == 0 ? ' ':vp->ch) & 0xFF;
#ifdef	MSDOS
			if ( n < ' ' || iskanji(n) )
			    tputc(033);
#endif
			tputc(n);
			dp->at = vp->at;
			dp->ch = vp->ch;
			vp++;
			dp++;
			sx++;
		    }
		}
	    } else {
		vp++;
		dp++;
	    }
	}
    }

#else
    for ( y = 0 ; y < lines_max ; y++ ) {
	vp = &(vram[y * cols_max]);
	dp = &(dram[y * cols_max]);
	for ( x = 0 ; x < cols_max ; x++ ) {
	    if ( vp[x].ch != dp[x].ch || vp[x].at != dp[x].at )
		break;
	}
	if ( x >= cols_max )
	    continue;

	for ( i = cols_max - 1 ; i > x ; i-- ) {
	    if ( vp[i].ch != dp[i].ch || vp[i].at != dp[i].at )
		break;
	}

	vp += x;
	dp += x;
	tputs(tgoto(CM, x, y), 1, tputc);

	for ( ; x <= i ; x++ ) {
	    if ( (vp->at & 0x40) != 0 ) {
		x--; vp--; dp--;
		if ( (vp->at & 0x80) == 0 ) {
		    x++; vp++; dp++;
		    vp->at &= 0xBF;
		}
	    }

	    if ( (vp->at & 0x0F) != at ) {
		n = vp->at & 0x0F;
		if ( (at & 0x07) != 0 && ME != NULL ) {
		    at = 0;
		    tputs(ME, 1, tputc);
		}
		if ( (n & 0x01) != 0 && MB != NULL && ME != NULL )
		    tputs(MB, 1, tputc);
		if ( (n & 0x02) != 0 && MD != NULL && ME != NULL )
		    tputs(MD, 1, tputc);
		if ( (n & 0x04) != 0 && MR != NULL && ME != NULL )
		    tputs(MR, 1, tputc);

		if ( (n & 0x08) != (at & 0x08) &&
				SO != NULL && SE != NULL )
		    tputs(((n & 0x08) ? SO : SE), 1, tputc);
		at = n;
	    }

	    if ( (vp[0].at & 0x80) != 0 && (vp[1].at & 0x40) != 0 ) {
		tputc(vp[0].ch);
		tputc(vp[1].ch);
		dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
		dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
		x++;
		    
	    } else {
		n = (vp->ch == 0 ? ' ':vp->ch) & 0xFF;
#ifdef	MSDOS
		if ( n < ' ' || iskanji(n) )
		    tputc(033);
#endif
		tputc(n);
		dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
	    }
	}
    }
#endif

    if ( (at & 0x07) != 0 && ME != NULL )
	tputs(ME, 1, tputc);
    if ( (at & 0x08) != 0 && SE != NULL )
	tputs(SE, 1, tputc);

    tputs(tgoto(CM, now_x, now_y), 1, tputc);

    if ( cur_dsp == TRUE && VE != NULL )
	tputs(VE, 1, tputc);

    tflush();
}
void	REFLUSH()
{
    memset(dram, 0xFF, sizeof(VRAM) * (cols_max * lines_max - 1));
}
void	SAVESCREEN()
{
    if ( save_flag == FALSE )
	memcpy(sram, vram, sizeof(VRAM) * cols_max * lines_max);
    save_flag = TRUE;
}
void	LOADSCREEN()
{
    memcpy(vram, sram, sizeof(VRAM) * cols_max * lines_max);
    save_flag = FALSE;
}
void	SAVECUR()
{
    back_x = now_x;
    back_y = now_y;
}
void	LOADCUR()
{
    now_x = back_x;
    now_y = back_y;
}
void    PUTANK(int ch)
{
    if ( ch == 0x20 )
	ch = 0;

    vram[now_x + now_y * cols_max].at = now_at;
    vram[now_x + now_y * cols_max].ch = ch;

    if ( ++now_x >= cols_max ) {
	now_x = 0;
	if ( ++now_y >= lines_max )
	    now_y = lines_max - 1;
    }
}
void    PUTC(int ch)
{
    PUTANK(ch);
}
void    PUTKAN(int ch)
{
    int n;
    static struct {
	int	jisR70;
	int	jis83;
    } jistab[]={
	{ 0xEF64,	0x84aa },
	{ 0xEF65,	0x84ab },
	{ 0xEF60,	0x84ac },
	{ 0xEF61,	0x84ad },
	{ 0xEF63,	0x84ae },
	{ 0xEF62,	0x84af },

	{ 0xEF88,	0x84a5 },
	{ 0xEF89,	0x84a6 },
	{ 0xEF8A,	0x84a7 },
	{ 0xEF87,	0x84a8 },
	{ 0xEF8B,	0x84a9 },

	{ 0xEF85,	0x849f },
	{ 0xEF86,	0x84a0 },
	{ 0xEF81,	0x84a1 },
	{ 0xEF82,	0x84a2 },
	{ 0xEF84,	0x84a3 },
	{ 0xEF83,	0x84a4 },

	{ 0xEF67,	0x84b0 },
	{ 0xEF68,	0x84b1 },
	{ 0xEF69,	0x84b2 },
	{ 0xEF66,	0x84b3 },
	{ 0xEF6A,	0x84b4 },

	{ 0xEF74,	0x84b5 },
	{ 0xEF76,	0x84b6 },
	{ 0xEF78,	0x84b7 },
	{ 0xEF72,	0x84b8 },
	{ 0xEF7A,	0x84b9 },

	{ 0,0 }
    };

    if ( R7 != TRUE ) {
	for ( n = 0 ; jistab[n].jisR70 != 0 ; n++ ) {
	    if ( ch == jistab[n].jisR70 ) {
		ch = jistab[n].jis83;
		break;
	    }
	}
    }

    if ( (now_x + 2) > cols_max ) {
	now_x = 0;
	if ( ++now_y >= lines_max )
	    now_y = lines_max - 1;
    }

    vram[now_x + now_y * cols_max].at = now_at | 0x80;
    vram[now_x + now_y * cols_max].ch = ch >> 8;
    now_x++;
    vram[now_x + now_y * cols_max].at = now_at | 0x40;
    vram[now_x + now_y * cols_max].ch = ch & 0xFF;
    now_x++;

    if ( now_x >= cols_max ) {
	now_x = 0;
	if ( ++now_y >= lines_max )
	    now_y = lines_max - 1;
    }
}
void    PUTS(char *str)
{
    while ( *str != '\0' ) {
	if ( iskanji(str[0]) && iskanji2(str[1]) ) {
	    PUTKAN(((str[0] & 0xFF) << 8) | (str[1] & 0xFF));
	    str += 2;
	} else
	    PUTANK(*(str++));
    }
}
void    FPUTS(char *form, ...)
{
    va_list arg;
    char    tmp[128];

    va_start(arg, form);
    vsprintf(tmp, form, arg);
    va_end(arg);

    PUTS(tmp);
}
void    LOCATE(int x, int y)
{
    if ( (now_x = x) >= cols_max )
	now_x = cols_max - 1;
    else if ( now_x < 0 )
	now_x = 0;
    if ( (now_y = y) >= lines_max )
	now_y = lines_max - 1;
    else if ( now_y < 0 )
	now_y = 0;
}
void    TOPSCR()
{
    now_x = now_y = 0;
}
void    BTMSCR()
{
    now_x = 0;
    now_y = lines_max - 1;
}
void    INSLINE()
{
    int y;

    for ( y = lines_max - 1 ; y > now_y ; y-- )
	memcpy(&(vram[y * cols_max]),
	       &(vram[(y - 1) * cols_max]), sizeof(VRAM) * cols_max);
    memset(&(vram[now_y * cols_max]), 0, sizeof(VRAM) * cols_max);
}
void    DELLINE()
{
    int y;

    for ( y = now_y ; y < (lines_max - 1) ; y++ )
	memcpy(&(vram[y * cols_max]),
	       &(vram[(y + 1) * cols_max]), sizeof(VRAM) * cols_max);
    memset(&(vram[(lines_max - 1) * cols_max]), 0, sizeof(VRAM) * cols_max);
}
void    FORSCROOL()
{
    int y;

    for ( y = 0 ; y < (lines_max - 1) ; y++ )
	memcpy(&(vram[y * cols_max]),
	       &(vram[(y + 1) * cols_max]), sizeof(VRAM) * cols_max);
    memset(&(vram[(lines_max - 1) * cols_max]), 0, sizeof(VRAM) * cols_max);
    scr_ofs++;
}
void	BAKSCROOL()
{
    int y;

    for ( y = lines_max - 1 ; y > 0 ; y-- )
	memcpy(&(vram[y * cols_max]),
	       &(vram[(y - 1) * cols_max]), sizeof(VRAM) * cols_max);
    memset(&(vram[0 * cols_max]), 0, sizeof(VRAM) * cols_max);
    scr_ofs--;
}
void    CLS()
{
    memset(vram, 0, sizeof(VRAM) * cols_max * lines_max);
    now_x = now_y = 0;
}
void    ERALINE()
{
    memset(&(vram[now_x + now_y * cols_max]), 0,
	sizeof(VRAM) * (cols_max - now_x));
}
void    ERASCR()
{
    int y;

    ERALINE();
    for ( y = now_y + 1 ; y < lines_max ; y++ )
	memset(&(vram[y * cols_max]), 0, sizeof(VRAM) * cols_max);
}
void    BAKSPC(int n)
{
    if ( (now_x -= n) < 0 )
	now_x = 0;
}
void    ATTSET(int n)
{
    while ( n-- > 0 ) {
	vram[now_x + now_y * cols_max].at &= 0xC0;
	vram[now_x + now_y * cols_max].at |= now_at;
	if ( ++now_x >= cols_max ) {
	    now_x = 0;
	    if ( ++now_y >= lines_max )
	        now_y = lines_max - 1;
	}
    }
}
void	BLINKCOL()
{
    now_at |= 0x01;
}
void	BOLDCOL()
{
    now_at |= 0x02;
}
void	REVCOL()
{
    now_at |= 0x04;
}
void	NOMCOL()
{
    now_at &= 0x38;
}
void    ACTCOL()
{
    now_at &= 0x07;
    now_at |= 0x08;
}
void    ERRCOL()
{
    now_at &= 0x07;
    now_at |= 0x10;
}
void    MSGCOL()
{
    now_at &= 0x07;
    now_at |= 0x18;
}
void    STDCOL()
{
    now_at &= 0x07;
}
void    REPCHR(int ch, int n)
{
    while ( n-- > 0 )
	PUTANK(ch);
}
void    CUROFF()
{
    cur_dsp = FALSE;
    if ( VI != NULL )
	tputs(VI, 1, tputc);
    tflush();
}
void    CURON()
{
    cur_dsp = TRUE;
    if ( VE != NULL )
	tputs(VE, 1, tputc);
    tflush();
}
void    BEEP()
{
    if ( VB != NULL )
	tputs(VB, 1, tputc);
    else
	tputc(0x07);
    tflush();
}
#ifdef	MSDOS
int     jis2sjis(chr)
int     chr;
{
    int    hi,lo;

    hi = (chr >> 8) & 0xff;
    lo = chr & 0xff;
    if ( (hi & 1) != 0 )
        lo += 0x1F;
    else
        lo += 0x7D;
    if ( lo >= 0x7F )
        lo++;
    hi = (hi - 0x21 >> 1) + 0x81;
    if ( hi > 0x9F )
        hi += 0x40;
    return (hi << 8 | lo);
}
int     sjis2jis(cd)
int     cd;
{
    int    hi,lo;

    hi = (cd >> 8) & 0xff;
    lo = cd & 0xff;
    hi -= ( hi <= 0x9f) ? 0x71 : 0xb1;
    hi = hi * 2 +1;
    if ( lo > 0x7f )
        lo--;
    if ( lo >= 0x9e ) {
        lo -= 0x7d;
        hi++;
    }
    else
        lo -= 0x1f;
    return (hi << 8 | lo);
}
void	SYSLINE(char *str)
{
    int     i,n;
    char far *p;
    union REGS regs;
    struct SREGS seg;
    static struct {
	char far	*chr;
	char far	*att;
    } adr_tbl;
    static struct {
	char		mode;
	char		attr;
	short		color;
    } att_buf[80];
    static char		chr_buf[80];

    memset(chr_buf, 0, 80);
    memset(att_buf, 0, sizeof(att_buf));
    n = 0;

    while ( n < 80 && *str != '\0' ) {
	if ( iskanji(*str) && iskanji2(*(str+1)) ) {
	    i = *(str++) << 8;
	    i |= (*(str++) & 0xFF);
	    i = sjis2jis(i);
	    chr_buf[n] = (i >> 8);
	    att_buf[n].mode = 1;
	    att_buf[n].attr = 0;
	    att_buf[n].color = 7;
	    n++;
	    chr_buf[n] = (i & 0xFF);
	    att_buf[n].mode = 3;
	    att_buf[n].attr = 0;
	    att_buf[n].color = 7;
	    n++;
	} else {
	    chr_buf[n] = *(str++);
	    att_buf[n].mode = 0;
	    att_buf[n].attr = 0;
	    att_buf[n].color = 7;
	    n++;
	}
    }

    adr_tbl.chr = (char far *)chr_buf;
    adr_tbl.att = (char far *)att_buf;

    p = (char far *)(&adr_tbl);
    regs.h.ah = 0x1F;
    regs.h.al = 1;
    regs.x.cx = 60;
    regs.h.dl = 1;
    seg.ds = FP_SEG(p);
    regs.x.di = FP_OFF(p);
    int86x(0x91,&regs,&regs,&seg);
}
#else
void	SYSLINE(char *str)
{
    static char *now = "";

    if ( str == NULL )
	str = now;
    now = str;
    tputs(tgoto(CM, 0, lines_sys), 1, tputc);
    while ( *str != '\0' )
	tputc(*(str++));
    tputs(CE, 1, tputc);
    tflush();
}
#endif
void	SCRNEND()
{
    SYSLINE("");
    tputs(tgoto(CM, 0, lines_sys), 1, tputc);
    tputs(CE, 1, tputc);
    tflush();
}
