/* DIVIDE_START=consol.c */
#ifndef		TYPE_LINUX
/*****************************************************************

	コンソ−ルメインル−チン

	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	0

/*****************************************************************
	ハ−ドウエアスクロ−ルを行うならHARDSCRを定義すること
******************************************************************/
#define	HARDSCR	0
#undef	HARDSCR

#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()のパラメ−タで使用の為)

******************************************************************/

static	void	SetDC2_s(unsigned char ch);
static	void	SetDC3_s(unsigned char ch);
static	void	SCurPs_s(unsigned char ch);
static	void	CurAtt_s(unsigned char ch);
static	void	AnsiCom(unsigned char ch);
static	void	SCurPs(unsigned char ch);
static	void	SVidAt(unsigned char ch);
static	void	CurAtt(unsigned char ch);
static	void	SetDC2(unsigned char ch);
static	void	SetDC3(unsigned char ch);
static	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;
	short	cons_cur_x=0;
	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=30;
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=14;
	short	cons_cur_lin= 0;
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に書き込みなどを行う関数群

	グラフィックの表示モ−ドなどを変更するならこの部分
	の修正を行う必要あり

******************************************************************/

#ifdef	HARDSCR
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,0);

    vram_cls((cons_off_x/2+(cons_max_y*SIZ_Y+cons_off_y)*512+
	      cons_wrt_ofs)&VMASK+cons_wrt_pag,
	      cons_max_x * SIZ_X,SIZ_Y,cons_now_bak);

    cons_wrt_ofs += (SIZ_Y*512);
    cons_wrt_ofs &= VMASK;
    vram_offset((cons_wrt_pag == 0 ? 17:21),cons_wrt_ofs/4);
}
#endif

static void	For_Scrool(int x,int y,int sx,int sy)
{
    vram_scrool(
		(	((x * SIZ_X + cons_off_x) / 2 +
			(y * SIZ_Y + cons_off_y ) * 512 +
			cons_wrt_ofs ) & VMASK
		) + cons_wrt_pag ,
		sx * SIZ_X,sy * SIZ_Y,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 * SIZ_Y + cons_off_y ) * 512 +
			cons_wrt_ofs ) & VMASK
		) + cons_wrt_pag ,
		sx * SIZ_X,sy * SIZ_Y,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 + cons_off_y ) * 512 +
			cons_wrt_ofs ) & VMASK
		) + cons_wrt_pag ,
		sx * SIZ_X,sy * SIZ_Y,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+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+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+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+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+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;
    }
}

/*****************************************************************

	ダイレクトコンソ−ル出力関数群

******************************************************************/

/*********** 以下は山本が追加した ***********/

/* struct window の buffer に文字を加える */
		void	w_putch( unsigned char ch );
extern	int		do_not_consol_out_sw;

/*********** ここまで山本が追加した ***********/

void    putch(unsigned char ch)
{
/*********** 以下は山本が追加した ***********/

	w_putch( ch );
	if ( do_not_consol_out_sw == FALSE )	goto ENDOF;

/*********** ここまで山本が追加した ***********/
    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[ 2048 ];

    va_start(arg,form);
    vsprintf((char *)tmp,form,arg);
    cputs(tmp);
    va_end(arg);
}

/*****************************************************************

	コンソ−ル割り込み(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;
    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 = 14;
/*
    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()

	無条件にコンソ−ルを画面一杯にオ−プンする

        注意:gccでは終了時にCON_close()を呼ぶこと

******************************************************************/

/*
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);
*/
}

/********************************************/
/*********** 以下は山本が追加した ***********/
/********************************************/
/* vram.s */
void	_vram_load(int addr , int size , int line , char *data );
void	_vram_save(int addr , int size , int line , char *data );

void	vram_load( int x1 , int y1 , int x2 , int y2 , char *data )
{
	_vram_load(
		(	( x1 / 2 + y1 * 512 ) & VMASK
		) + cons_wrt_pag ,
		x2 - x1 + 1 , y2 - y1 + 1 , data );
}

void	vram_save( int x1 , int y1 , int x2 , int y2 , char *data )
{
	_vram_save(
		(	( x1 / 2 + y1 * 512 ) & VMASK
		) + cons_wrt_pag ,
		x2 - x1 + 1 , y2 - y1 + 1 , data );
}

#endif	/* TYPE_LINUX */

/* DIVIDE_END */
