/*****************************************************************

	コンソ−ルメインル−チン

	1991.01.01	make by ken

【対応コントロ−ルコ−ド】

        $08             バック・スペ−ス
        $09             ＴＡＢ
        $0A             ラインフィ−ルド
        $0B             ホ−ム・ポジション
        $0C             クリア・スクリ−ン
        $0D             キャリッジ・リタ−ン
        $11+n           セット・ビデオ・アトリビュ−ト
        $12+x+y         セット・カ−ソル・ポジション
        $13+n+c         リピ−ト・キャラクタ
        $15             クリア・スクリ−ン
        $16             クリア・スクリ−ン
        $1B             エスケ−プ・シ−ケンス（下記参照）
        $1C             カ−ソル・ライト
        $1D             カ−ソル・レフト
        $1E             カ−ソル・アップ
        $1F             カ−ソル・ダウン

【対応エスケ−プシ−ケンス】
 
        ESC+'*'         クリア・スクリ−ン
        ESC+'T'         イレ−ス・ライン
        ESC+'Y'         イレ−ス・スクリ−ン
        ESC+'E'         インサ−ト・ライン
        ESC+'R'         デリ−ト・ライン
        ESC+'='+y+x     セット・カ−ソル・ポジション
        ESC+'G'+v       セット・ビデオ・アトリビュ−ト
        ESC+'.'+n+n     セット・カ−ソル・アトリビュ−ト
        ESC+'K'         漢字モ−ド・セット
        ESC+'C'         ＡＮＫモ−ド・セット
        ESC+'['.....    ＡＮＳＩエスケ−プ（下記参照）
        ESC+n           上記以外のコ−ドを表示
 
        ESC[y;xH        セット・カ−ソル・ポジション
        ESC[y;xf        セット・カ−ソル・ポジション
        ESC[nA          カ−ソル・アップ
        ESC[nB          カ−ソル・ダウン
        ESC[nC          カ−ソル・ライト
        ESC[nD          カ−ソル・レフト
        ESC[s           カ−ソル位置保存
        ESC[u           保存したカ−ソル位置を復帰
        ESC[nJ          クリア・スクリ−ン
        ESC[nK          イレ−ス・ライン
        ESC[nL          インサ−ト・ライン
        ESC[nM          デリ−ト・ライン
        ESC[n...m       セット・ビデオ・アトリビュ−ト
	    ESC[nv			カ−ソルのON/OFF

******************************************************************/

#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>
#include    <string.h>
#include    <ctype.h>
#include    "dspstr.h"

/*****************************************************************
	文字色の変化が少ないならCOLTBLを定義すること
******************************************************************/
#define	COLTBL	1

/*****************************************************************
	ハ−ドウエアスクロ−ルを行うならHARDSCRを定義すること
******************************************************************/
#define	HARDSCR	0

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

#define	SIZ_X	8		/* 横のANK文字サイズ */
#define	SIZ_Y	16		/* 縦の文字サイズ 変更不可! */
#define	TAB	8			/* タブサイズ */

#define	VMASK	0x3FFFF		/* VRAMのマスク */

/*****************************************************************

	外部関数の定義(CONS.ASM参照)

******************************************************************/

void	CON_bios_set(void);
void	CON_bios_ret(void);

/*****************************************************************

	内部呼び出し関数の定義(NextChr()のパラメ−タで使用の為)

******************************************************************/

void	SetDC2_s(unsigned char ch);
void	SetDC3_s(unsigned char ch);
void	SCurPs_s(unsigned char ch);
void	CurAtt_s(unsigned char ch);
void	AnsiCom(unsigned char ch);
void	SCurPs(unsigned char ch);
void	SVidAt(unsigned char ch);
void	CurAtt(unsigned char ch);
void	SetDC2(unsigned char ch);
void	SetDC3(unsigned char ch);
void	EscCom(unsigned char ch);

/*****************************************************************

	レジスタフレ−ムの構造定義

	CONS.ASM内の割り込みル−チンから渡される
	構造はPUSHADそのものである

******************************************************************/

typedef union {
    struct {
	unsigned int	edi;
	unsigned int	esi;
	unsigned int	edp;
	unsigned int	esp;
	unsigned int	ebx;
	unsigned int	edx;
	unsigned int	ecx;
	unsigned int	eax;
    } e;
    struct {
	unsigned short di;
	unsigned short __di;
	unsigned short si;
	unsigned short __si;
	unsigned short bp;
	unsigned short __bp;
	unsigned short sp;
	unsigned short __sp;
	unsigned short bx;
	unsigned short __bx;
	unsigned short dx;
	unsigned short __dx;
	unsigned short cx;
	unsigned short __cx;
	unsigned short ax;
	unsigned short __ax;
    } x;
    struct {
	unsigned short di;
	unsigned short __di;
	unsigned short si;
	unsigned short __si;
	unsigned short bp;
	unsigned short __bp;
	unsigned short sp;
	unsigned short __sp;
	unsigned char bl, bh;
	unsigned short __bx;
	unsigned char dl, dh;
	unsigned short __dx;
	unsigned char cl, ch;
	unsigned short __cx;
	unsigned char al, ah;
	unsigned short __ax;
    } h;
} REGS;

/*****************************************************************

	コンソ−ルの各種変数定義

******************************************************************/

static short	cons_open_flg=FALSE;
static int	cons_wrt_pag=PAGE0;
static int	cons_wrt_ofs=0;
static short	cons_cur_x=0;
static short	cons_cur_y=0;
static short	cons_bak_x=0;
static short	cons_bak_y=0;
static short	cons_off_x=0;
static short	cons_off_y=0;
static short	cons_max_x=80;
static short	cons_max_y=25;
static short	cons_bak_chr=0;
static short	cons_kan_bak=0;
static short	cons_kan_flg=TRUE;
static short	cons_now_col=15;
static short	cons_now_bak=0;
static short	cons_def_col=7;
static short	cons_def_bak=0;
static short	cons_cur_dsp=0;
static short	cons_cur_ofs=16;
static short	cons_cur_lin=2;
static short	cons_ext_flg=FALSE;
static void	(*cons_ext_prc)(unsigned char ch);
static short	cons_esc_cnt=0;
static char	cons_esc_prm[32];

/*****************************************************************

	コンソ−ル操作の下位関数群

	コンソ−ル座標から実際のグラフィック座標に変換など
	を行いVRAMに書き込みなどを行う関数群

	グラフィックの表示モ−ドなどを変更するならこの部分
	の修正を行う必要あり

******************************************************************/

static void	Hard_Scrool(void)
{
    if ( cons_off_y > 0 )
        vram_cls((cons_off_x/2+cons_off_y*512+
	      cons_wrt_ofs)&VMASK+cons_wrt_pag,
	      cons_max_x * SIZ_X,(SIZ_Y+3),0);

    vram_cls((cons_off_x/2+(cons_max_y*(SIZ_Y+3)+cons_off_y)*512+
	      cons_wrt_ofs)&VMASK+cons_wrt_pag,
	      cons_max_x * SIZ_X,(SIZ_Y+3),cons_now_bak);

    cons_wrt_ofs += ((SIZ_Y+3)*512);
    cons_wrt_ofs &= VMASK;
    vram_offset((cons_wrt_pag == 0 ? 17:21),cons_wrt_ofs/4);
}
static void	For_Scrool(int x,int y,int sx,int sy)
{
    vram_scrool(((x*SIZ_X+cons_off_x)/2+
		 (y*(SIZ_Y+3)+cons_off_y)*512+
		 cons_wrt_ofs)&VMASK+cons_wrt_pag,
		sx * SIZ_X,sy * (SIZ_Y+3),cons_now_bak);
}
static void	Bak_Scrool(int x,int y,int sx,int sy)
{
    vram_bk_scr(((x*SIZ_X+cons_off_x)/2+
		 ((y+sy)*(SIZ_Y+3)+cons_off_y)*512+
		 cons_wrt_ofs)&VMASK+cons_wrt_pag,
		sx * SIZ_X,sy * (SIZ_Y+3),cons_now_bak);
}
static void	Scr_cls(int x,int y,int sx,int sy)
{
    vram_cls(((x*SIZ_X+cons_off_x)/2+
	      (y*(SIZ_Y+3)+cons_off_y)*512+
	      cons_wrt_ofs)&VMASK+cons_wrt_pag,
	     sx * SIZ_X,sy * (SIZ_Y+3),cons_now_bak);
}
static void	Scrool(void)
{
    if ( ++cons_cur_y >= cons_max_y ) {
	cons_cur_y = cons_max_y - 1;
#ifdef	HARDSCR
	Hard_Scrool();
#else
	For_Scrool(0,0,cons_max_x,cons_max_y - 1);
#endif
    }
}
static void	ank_put(unsigned char ch)
{
#ifdef	COLTBL
    cwrt_ank(ch,((cons_cur_x*SIZ_X+cons_off_x)/2+
	        (cons_cur_y*(SIZ_Y+3)+cons_off_y)*512+
		cons_wrt_ofs)&VMASK+cons_wrt_pag);
#else
    wrt_ank(ch,((cons_cur_x*SIZ_X+cons_off_x)/2+
	        (cons_cur_y*(SIZ_Y+3)+cons_off_y)*512+
		cons_wrt_ofs)&VMASK+cons_wrt_pag,
		cons_now_col,cons_now_bak);
#endif

    if ( ++cons_cur_x >= cons_max_x ) {
	cons_cur_x = 0;
	Scrool();
    }
}
static void	kan_put(unsigned short ch)
{
    if ( cons_cur_x >= (cons_max_x - 1) ) {
	cons_cur_x = 0;
	Scrool();
    }

#ifdef	COLTBL
    cwrt_kan(ch,((cons_cur_x*SIZ_X+cons_off_x)/2+
	        (cons_cur_y*(SIZ_Y+3)+cons_off_y)*512+
		cons_wrt_ofs)&VMASK+cons_wrt_pag);
#else
    wrt_kan(ch,((cons_cur_x*SIZ_X+cons_off_x)/2+
	        (cons_cur_y*(SIZ_Y+3)+cons_off_y)*512+
		cons_wrt_ofs)&VMASK+cons_wrt_pag,
		cons_now_col,cons_now_bak);
#endif

    if ( (cons_cur_x += 2) >= cons_max_x ) {
	cons_cur_x = 0;
	Scrool();
    }
}
static void	cur_put(void)
{
    wrt_cur(((cons_cur_x*SIZ_X+cons_off_x)/2+
	     (cons_cur_y*(SIZ_Y+3)+cons_off_y+cons_cur_ofs)*512+
	     cons_wrt_ofs)&VMASK+cons_wrt_pag,
	    cons_cur_lin);
}

/*****************************************************************

	コントロ−ルコ−ドの制御関数群

******************************************************************/

static void    NextChr(void (*sub)(unsigned char ch))
{
    cons_ext_flg = TRUE;
    cons_ext_prc = sub;
}
static void    PutBS(void)
{
    if ( --cons_cur_x < 0 ) {
        cons_cur_x = cons_max_x - 1;
        if ( --cons_cur_y < 0 )
            cons_cur_y = 0;
    }
}
static void    PutTAB(void)
{
    int     n;

    n = TAB - (cons_cur_x % TAB);
    while ( n-- > 0 )
	ank_put(' ');
}
static void    PutLF(void)
{
    Scrool();
}
static void    PutHOME(void)
{
    cons_cur_x = cons_cur_y = 0;
}
static void    PutCLS(void)
{
    Scr_cls(0,0,cons_max_x,cons_max_y);
    cons_cur_x = cons_cur_y = 0;
}
static void    PutCR(void)
{
    cons_cur_x = 0;
}
static void    CurRit(void)
{
    if ( ++cons_cur_x >= cons_max_x )
        cons_cur_x = 0;
}
static void    CurLft(void)
{
    if ( --cons_cur_x < 0 )
        cons_cur_x = cons_max_x - 1;
}
static void    CurUp(void)
{
    if ( --cons_cur_y < 0 )
        cons_cur_y = cons_max_y - 1;
}
static void    CurDwn(void)
{
    if ( ++cons_cur_y >= cons_max_y )
        cons_cur_y = 0;
}
static void    SVidAt(unsigned char ch)
{
    int   c,b;

    c = (ch & 0x07) | 0x08;
    b = cons_now_bak;
    if ( (ch & 0x20) != 0 )
	c &= 0xF7;
    if ( (ch & 0x18) != 0 ) {
	b = c;
	c = cons_now_bak;
    }
    cons_now_col = c;
    cons_now_bak = b;
#ifdef	COLTBL
    ctblset(c,b);
#endif
}
static void    SetDC2_s(unsigned char ch)
{
    cons_cur_x = cons_bak_chr;
    cons_cur_y = ch;
    if ( cons_cur_x < 0 )	    cons_cur_x = 0;
    if ( cons_cur_x >= cons_max_x ) cons_cur_x = cons_max_x - 1;
    if ( cons_cur_y < 0 ) 	    cons_cur_y = 0;
    if ( cons_cur_y >= cons_max_y ) cons_cur_y = cons_max_y - 1;
}
static void    SetDC2(unsigned char ch)
{
    cons_bak_chr = ch;
    NextChr(SetDC2_s);
}
static void    SetDC3_s(unsigned char ch)
{
    while ( cons_bak_chr-- > 0 )
        ank_put(ch);
}
static void    SetDC3(unsigned char ch)
{
    cons_bak_chr = ch;
    NextChr(SetDC3_s);
}
static void    EraLin(void)
{
    Scr_cls(cons_cur_x,cons_cur_y,cons_max_x - cons_cur_x,1);
}
static void    EraScr(void)
{
    EraLin();
    if ( (cons_cur_y + 1) < cons_max_y )
	Scr_cls(0,cons_cur_y+1,cons_max_x,cons_max_y-cons_cur_y-1);
}
static void    InsLin(void)
{
    if ( (cons_cur_y + 1) < cons_max_y )
	Bak_Scrool(0,cons_cur_y,cons_max_x,cons_max_y-cons_cur_y-1);
    else
	Scr_cls(0,cons_cur_y,cons_max_x,1);
}
static void    DelLin(void)
{
    if ( (cons_cur_y + 1) < cons_max_y )
	For_Scrool(0,cons_cur_y,cons_max_x,cons_max_y-cons_cur_y-1);
    else
	Scr_cls(0,cons_cur_y,cons_max_x,1);
}
static void    SCurPs_s(unsigned char ch)
{
    cons_cur_y = cons_bak_chr - ' ';
    cons_cur_x = ch - ' ';
    if ( cons_cur_x < 0 )	    cons_cur_x = 0;
    if ( cons_cur_x >= cons_max_x ) cons_cur_x = cons_max_x - 1;
    if ( cons_cur_y < 0 )	    cons_cur_y = 0;
    if ( cons_cur_y >= cons_max_y ) cons_cur_y = cons_max_y - 1;
}
static void    SCurPs(unsigned char ch)
{
    cons_bak_chr = ch;
    NextChr(SCurPs_s);
}
static void	CurAtt_s(unsigned char ch)
{
    cons_cur_ofs = cons_bak_chr & 0x1F;
    if ( (cons_cur_lin = (ch & 0x1F) - cons_cur_ofs) <= 0 )
	cons_cur_lin = 1;
}
static void	CurAtt(unsigned char ch)
{
    cons_bak_chr = ch;
    NextChr(CurAtt_s);
}

/*****************************************************************

	ANSIエスケ−プシ−ケンス制御関数群

******************************************************************/

static void    AnsiH(void)
{
    if ( cons_esc_prm[0] > 0 ) cons_esc_prm[0]--;
    if ( cons_esc_prm[1] > 0 ) cons_esc_prm[1]--;
    cons_cur_y = cons_esc_prm[0];
    cons_cur_x = cons_esc_prm[1];
    if ( cons_cur_x < 0 )	    cons_cur_x = 0;
    if ( cons_cur_x >= cons_max_x ) cons_cur_x = cons_max_x - 1;
    if ( cons_cur_y < 0 )	    cons_cur_y = 0;
    if ( cons_cur_y >= cons_max_y ) cons_cur_y = cons_max_y - 1;
}
static void    AnsiA(void)
{
    if ( (cons_cur_y -= cons_esc_prm[0]) < 0 )
        cons_cur_y = 0;
}
static void    AnsiB(void)
{
    if ( (cons_cur_y += cons_esc_prm[0]) >= cons_max_y )
        cons_cur_y = cons_max_y - 1;
}
static void    AnsiC(void)
{
    if ( (cons_cur_x += cons_esc_prm[0]) >= cons_max_x )
        cons_cur_x = cons_max_x - 1;
}
static void    AnsiD(void)
{
    if ( (cons_cur_x -= cons_esc_prm[0]) < 0 )
        cons_cur_x = 0;
}
static void    Ansis(void)
{
    cons_bak_x = cons_cur_x;
    cons_bak_y = cons_cur_y;
}
static void    Ansiu(void)
{
    cons_cur_x = cons_bak_x;
    cons_cur_y = cons_bak_y;
}
static void    AnsiJ(void)
{
    switch(cons_esc_prm[0]) {
        case 0: EraScr(); break;
        case 1: 
	    if ( cons_cur_x > 0 )
		Scr_cls(0,cons_cur_y,cons_cur_x,1);
	    if ( cons_cur_y > 0 )
		Scr_cls(0,0,cons_max_x,cons_cur_y);
	    break;
        case 2: PutCLS(); break;
    }
}
static void    AnsiK(void)
{
    switch(cons_esc_prm[0]) {
        case 0: EraLin(); break;
        case 1:
	    if ( cons_cur_x > 0 )
		Scr_cls(0,cons_cur_y,cons_cur_x,1);
            break;
        case 2:
	    Scr_cls(0,cons_cur_y,cons_max_x,1);
	    break;
    }
}
static void    AnsiM(void)
{
    while ( cons_esc_prm[0]-- > 0 )
        DelLin();
    cons_cur_x = 0;
}
static void    AnsiL(void)
{
    while ( cons_esc_prm[0]-- > 0 )
        InsLin();
    cons_cur_x = 0;
}
static void    Ansim(void)
{
    int     c;
    int     i,n;
    static char ansiatt[]={ 0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x08,0x00 };
    static char ansicol[]={ 0,2,4,6,1,3,5,7 };
 
    c = cons_def_col;
    for ( n = 0 ; n < cons_esc_cnt ; n++ ) {
        if ( (i = cons_esc_prm[n]) >= 1 && i <= 7 ) {
            c |= ansiatt[i];
	} else if ( i == 0 ) {
	    c = cons_def_col;
	    cons_now_bak = cons_def_bak;
        } else if ( i >= 30 && i <= 38 ) {
            c &= 0xF8;
            c |= ansicol[i-30];
        } else if ( i >= 40 && i <= 47 ) {
            cons_now_bak = ansicol[i-40];
	}
    }
    SVidAt(c);
}
static void	Ansiv(void)
{
    cons_cur_dsp = cons_esc_prm[0];
}
static void    AnsiCom(unsigned char ch)
{
    if ( ch == ';' && cons_esc_cnt < 8 )
        cons_esc_cnt++;
    else if ( ch >= '0' && ch <= '9' )
        cons_esc_prm[cons_esc_cnt] = 
		cons_esc_prm[cons_esc_cnt] * 10 + (ch - '0');
    else if ( ch != ' ' ) {
        cons_esc_cnt++;
        switch(ch) {
            case 'H': AnsiH(); break;
            case 'f': AnsiH(); break;
            case 'A': AnsiA(); break;
            case 'B': AnsiB(); break;
            case 'C': AnsiC(); break;
            case 'D': AnsiD(); break;
            case 's': Ansis(); break;
            case 'u': Ansiu(); break;
            case 'J': AnsiJ(); break;
            case 'K': AnsiK(); break;
            case 'm': Ansim(); break;
            case 'M': AnsiM(); break;
            case 'L': AnsiL(); break;
            case 'v': Ansiv(); break;
        }
        return;
    }
    NextChr(AnsiCom);
}
static void    AnsiESC(void)
{
    memset(cons_esc_prm,0,32);
    cons_esc_cnt = 0;
    NextChr(AnsiCom);
}
static void    EscCom(unsigned char ch)
{
    switch(ch) {
        case '*': PutCLS(); break;
        case 'T': EraLin(); break;
        case 'Y': EraScr(); break;
        case 'E': InsLin(); break;
        case 'R': DelLin(); break;
        case '=': NextChr(SCurPs); break;
        case 'G': NextChr(SVidAt); break;
        case 'K': cons_kan_flg = TRUE; break;
        case 'C': cons_kan_flg = FALSE; break;
	case '.': NextChr(CurAtt); break;
        case '[': AnsiESC(); break;
        default:  ank_put(ch); break;
    }
}

/*****************************************************************

	ダイレクトコンソ−ル出力関数群

******************************************************************/

void    putch(unsigned char ch)
{
    if ( cons_cur_dsp == 0 )
	cur_put();

    if ( cons_ext_flg != FALSE ) {
	cons_ext_flg = FALSE;
	(*cons_ext_prc)(ch);
        goto ENDOF;
    }

    if ( cons_kan_bak != 0 ) {
	if ( iskanji2(ch) ) {
	    kan_put((cons_kan_bak << 8) | ch);
	    cons_kan_bak = 0;
	    goto ENDOF;
	}
	ank_put(cons_kan_bak);
	cons_kan_bak = 0;
    }

    switch(ch) {
    case 0x08: PutBS(); break;
    case 0x09: PutTAB(); break;
    case 0x0A: PutLF(); break;
    case 0x0B: PutHOME(); break;
    case 0x0C: PutCLS(); break;
    case 0x0D: PutCR(); break;

    case 0x12: NextChr(SetDC2); break;
    case 0x13: NextChr(SetDC3); break;
    case 0x15: PutCLS(); break;
    case 0x16: PutCLS(); break;

    case 0x1B: NextChr(EscCom); break;

    case 0x1C: CurRit(); break;
    case 0x1D: CurLft(); break;
    case 0x1E: CurUp(); break;
    case 0x1F: CurDwn(); break;

    default:
	if ( cons_kan_flg != FALSE && iskanji(ch) )
	    cons_kan_bak = ch;
	else if ( ch != '\0' )
	    ank_put(ch);
	break;
    }

ENDOF:
    if ( cons_cur_dsp == 0 )
	cur_put();
}
void	cputs(char *str)
{
    while ( *str != '\0' ) {
	if ( *str == '\n' )
	    putch('\r');
	putch(*(str++));
    }
}
void	cprintf(char *form,...)
{
    va_list arg;
    char    tmp[256];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    cputs(tmp);
    va_end(arg);
}
/*-----------------------------------------------------------------------*/
void	cur_type(int sw)
{
	if ( sw ) {
		cons_cur_ofs = 16;
		cons_cur_lin = 2;
	}
	else {
		cons_cur_ofs = 0;
		cons_cur_lin = 18;
	}
}
/*-----------------------------------------------------------------------*/

/*****************************************************************

	コンソ−ル割り込み(INT 29h)のメイン関数

	CONS.ASM内の割り込みル−チンから呼ばれる関数

******************************************************************/

void	CON_bios(REGS *reg)
{
    putch(reg->h.al);
}

/*****************************************************************

	下位のコンソ−ルオ−プン関数 CON_open()

【注意】CON_open()を使用した場合は終了時に必ずCON_close()を
	呼び出すこと!

int	pag;	表示VRAMペ−ジ番号 (0 or 1)
int	x1;	コンソ−ル表示左上X座標(0 - 639)
int	y1;	コンソ−ル表示左上Y座標(0 - 479)
int	x2;	コンソ−ル表示右下X座標(0 - 639) x2 > x1
int	y2;	コンソ−ル表示右下Y座標(0 - 479) y2 > y1
int	chc;	文字色(0 - 15)
int	bkc;	背景色(0 - 15)

******************************************************************/

void	CON_open(int pag,int x1,int y1,int x2,int y2,int chc,int bkc)
{
    if ( cons_open_flg != FALSE )
	return;

    cons_cur_x = 0;
    cons_cur_y = 0;
    cons_kan_bak = 0;
    cons_off_x = x1;
    cons_off_y = y1;
    cons_max_x = (x2 - x1 + 1) /  SIZ_X;
    cons_max_y = (y2 - y1 + 1) / (SIZ_Y + 3);
    cons_kan_flg = TRUE;
    cons_now_col = chc;
    cons_def_col = (chc & 7) | ((chc & 8) ? 0:0x20);
    cons_def_bak = cons_now_bak = bkc;
    cons_cur_dsp = 0;
    cons_cur_ofs = 16;
    cons_cur_lin = 2;
    cons_wrt_pag = (pag == 0 ? PAGE0:PAGE1);
    cons_wrt_ofs = 0;

    PutCLS();
    cur_put();
#ifdef	COLTBL
    ctblset(chc,bkc);
#endif
    CON_bios_set();
    cons_open_flg = TRUE;
}
void	CON_close(void)
{
    if ( cons_open_flg != FALSE )
	CON_bios_ret();
    cons_open_flg = FALSE;
}

/*****************************************************************

	上位のコンソ−ルオ−プン関数 copen()

	無条件にコンソ−ルを画面一杯にオ−プンする

******************************************************************/

static onexit_t f_ret=(onexit_t)0;

static onexit_t cclose(void)
{
    CON_close();
    return f_ret;
}
void	copen(void)
{
    CON_open(0,0,0,639,479,15,0);
    f_ret = onexit(cclose);
}
