#include "ownincs/VT340console.h"


/* allowed globals.. */
struct	ExecBase			*SysBase;
struct	DosLibrary		*DOSBase;
struct	GfxBase			*GfxBase;
struct	IntuitionBase	*IntuitionBase;
struct	Library			*DiskfontBase;


/*VOID KPrintF(UBYTE *, ...);*/

              /* Support Funktionen zu VT340 Emulator.. */


VOID VT340_resetcon(struct VT340Console *con, BOOL ris)
{
	con->ustat |=  (U_CURSOR);
	con->ustat &= ~(U_INSERT | U_KEYAPP | U_CURAPP);

	con->ustat &= ~(U_HOST_STATUSLINE | U_HOST_STATUSLINE_ACTIVE);
	VT340_deleteStatusLine(con, FALSE);

	con->tstat &= ~(T_WRAP);

	con->ordc	= 0;
	con->ordcol = 1;
	con->DECSCA	= ERASEABLE;


	VT340_cancel(con);

	if(ris != FALSE)	/* Reset to Initial State */
	{
		UWORD i;

		con->identify = con->r_identify;

/**********/

		if(con->r_tstat & T_WRAP)
			con->tstat |= T_WRAP;
		else
			con->tstat &= ~T_WRAP;

/**********/

		if(con->r_ustat & U_CURSOR)
			con->ustat |= U_CURSOR;
		else
			con->ustat &= ~U_CURSOR;

		if(con->r_ustat & U_NEWLINE)
			con->ustat |= U_NEWLINE;
		else
			con->ustat &= ~U_NEWLINE;

		if(con->r_ustat & U_INSERT)
			con->ustat |= U_INSERT;
		else
			con->ustat &= ~U_INSERT;

/**********/

		con->pstat = con->r_pstat;		/* private settings */

/**********/

		con->gstat &= ~(G_FULLSCREEN | G_FORMFEED);

		VT340_resetscreen(con, TRUE);

		setmem(con->tabs, con->columns, 0);
		for(i=9; i<con->columns; i+=8)
			con->tabs[i] = 'T';
	}
	else
	{
		con->tstat &= ~(T_USE_REGION);
		con->top = con->firstline;
		con->bot = con->lastline;
	}

	con->m_row = con->row;	/* MAIN ACTIVE DISPLAY */
	con->m_col = con->col;

	VT340_savecursor(con, NULL, 0);

	VT340_resetstyles(con);

	VT340_resetfonts(con);

	VT340_createOwnStatusLine(con);
}


VOID VT340_resetstyles(struct VT340Console *con)
{
	con->attr	= FS_NORMAL;
	con->apen	= con->foreground_pen;
	con->bpen	= BACKGROUND_PEN;

	SetAPen(con->rp, con->apen);
	SetBPen(con->rp, con->bpen);
	SetDrMd(con->rp, JAM2);
	SetSoftStyle(con->rp, (UWORD)con->attr, FSF_UNDERLINED);
}


VOID VT340_resetfonts(struct VT340Console *con)
{
	SetFont(con->rp, con->dc_font);

	con->upss	 = (con->pstat & P_ISO_LATIN1) ? ISO_SUPPLEMENTAL : DEC_SUPPLEMENTAL;
	con->gset[0] = ASCII;
	con->gset[1] = ASCII;
	con->gset[2] = con->upss;
	con->gset[3] = con->upss;
	VT340_setlset(con, 0);	/* ASCII */
	VT340_setrset(con, 2);	/* USER-PREFERRED SUPPLEMENTAL SET */
	con->slset	= con->s_lset = con->lset;
	con->s_rset	= con->rset;
}


VOID VT340_locked(struct VT340Console *con, BOOL locked)
{
	if(con->pstat & P_OWN_STATUSLINE)
	{
		UBYTE *text;

		SetFont(con->rp, con->topazfont);
		SetDrMd(con->rp, JAM2|INVERSVID);
		SetSoftStyle(con->rp, FS_NORMAL, FSF_UNDERLINED);
		SetBPen(con->rp, BACKGROUND_PEN);
		SetAPen(con->rp, con->foreground_pen);

		text = (locked) ? "LOCKED" : "READY ";

		Move(con->rp, 144, con->statusline * FONT_YSIZE - (FONT_YSIZE - BOTLINE));
		Text(con->rp, text, 6);

		SetAPen(con->rp, con->apen);
		SetBPen(con->rp, con->bpen);
		SetSoftStyle(con->rp, (UWORD)con->attr, FSF_UNDERLINED);
		SetDrMd(con->rp, JAM2);
		SetFont(con->rp, con->dc_font);
	}
}


/* cancels any sequence.. */
VOID VT340_cancel(struct VT340Console *con)
{
	if(con->inDCS  ||  con->inPrivate)
		VT340_locked(con, FALSE);

	con->inESC		= FALSE;
	con->inCSI		= FALSE;
	con->inTEK		= FALSE;
	con->inDCS		= FALSE;
	con->inPrivate	= FALSE;

	con->argc		= 0;
	con->args[0]	= NUL;
	con->args[1]	= NUL;
	con->icnt		= 0;
	con->inter[0]	= NUL;
	con->lastPRIVc	= NUL;

	con->VT52_dca = FALSE;	/* VT-52 Direct Cursor Address */
}


VOID VT340_cursorflip(struct VT340Console *con)
{
	ULONG row, col, xsize=XSIZE, off=1;

	row = con->row - 1;
	col = con->col - 1;
	if(col > (con->columns-1))
		col = con->columns-1;
	if(*(con->rows + con->row))
	{
		xsize <<= 1;
		col <<= 1;
		off <<= 1;
	}
	SetDrMd(con->rp, COMPLEMENT);
	RectFill(con->rp, col * XSIZE, (row+1) * con->ysize - FONT_YSIZE,
	 col * XSIZE + xsize - off, (row+1) * con->ysize  - 1);
	SetDrMd(con->rp, JAM2);
}


VOID VT340_eraselinebeg(struct VT340Console *con)
{
	UWORD y, xsize;

	xsize	= XSIZE;
	if(*(con->rows + con->row))
		xsize	<<= 1;

	y = con->row * con->ysize;
	VT340_cleararea(con->rp, 0, y - con->ysize, con->col * xsize, y);
}


VOID VT340_eraselineend(struct VT340Console *con)
{
	UWORD y, lim, xsize;

	xsize	= XSIZE;
	lim	= con->columns;
	if(*(con->rows + con->row))
	{
		xsize	<<= 1;
		lim	<<= 1;
	}

	y = con->row * con->ysize;
	VT340_cleararea(con->rp, (con->col-1) * xsize, y - con->ysize, con->width, y);
}


VOID VT340_eraselines(struct VT340Console *con, UWORD row, UWORD cnt)
{
	UWORD y1, y2;

	if(!cnt)
		return;

	y1 = row * con->ysize;
	y2 = (row + cnt) * con->ysize;

	VT340_cleararea(con->rp, 0, y1, con->width, y2);
}


VOID VT340_erasescrbeg(struct VT340Console *con)
{
	UWORD cnt = con->row - 1;

	if(con->row > 1)
		VT340_cleararea(con->rp, 0, (con->firstline-1) * con->ysize, con->width, cnt * con->ysize);
	VT340_eraselinebeg(con);
}


VOID VT340_eraseactivescreen(struct VT340Console *con)
{
	VT340_cleararea(con->rp, 0, (con->firstline-1) * con->ysize, con->width, con->lastline * con->ysize);
	VT340_clearactiverowregister(con);
}


VOID VT340_erasewholescreen(struct VT340Console *con)
{
	SetRast(con->rp, 0);
	VT340_clearwholerowregister(con);
}


VOID VT340_cleararea(struct RastPort *rp, UWORD x1, UWORD y1, UWORD x2, UWORD y2)
{
	ClipBlit(rp, x1, y1, rp, x1, y1, x2 - x1, y2 - y1, 0);
}


#define FIRSTLCHAR          32
#define FIRSTRCHAR          (FIRSTLCHAR + 128)
#define CHARCOUNT           (128 - FIRSTLCHAR)


	/* G_reg =>> G0 || G1 || G2 || G3 */

VOID VT340_setlset(struct VT340Console *con, UWORD G_reg)
{
	struct TextFont *df;
	UWORD dmod, *loc;
	UBYTE *scp, *dcp, cnt1, cnt2;

	con->lset = G_reg;
	cnt2 = con->gset[G_reg];

	scp	= con->fonts[cnt2];
	df		= con->dc_font;
	dmod	= df->tf_Modulo;

	cnt1 = CHARCOUNT;
	while(cnt1--)
	{
		dcp = (UBYTE *)df->tf_CharData;
		loc = (UWORD *)df->tf_CharLoc;
		loc += (cnt1 + FIRSTLCHAR) << 1;
		dcp += *loc >> 3;

		for(cnt2=0; cnt2<FONT_YSIZE; cnt2++)
		{
			*dcp = *scp;
			scp++;
			dcp += dmod;
		}
	}
}


	/* G_reg =>> G0 || G1 || G2 || G3 */

VOID VT340_setrset(struct VT340Console *con, UWORD G_reg)
{
	struct TextFont *df;
	UWORD dmod, *loc;
	UBYTE *scp, *dcp, cnt1, cnt2;

	con->rset = G_reg;
	cnt2 = con->gset[G_reg];

	scp	= con->fonts[cnt2];
	df		= con->dc_font;
	dmod	= df->tf_Modulo;

	cnt1 = CHARCOUNT;
	while(cnt1--)
	{
		dcp = (UBYTE *)df->tf_CharData;
		loc = (UWORD *)df->tf_CharLoc;
		loc += (cnt1 + FIRSTRCHAR) << 1;
		dcp += *loc >> 3;

		for(cnt2=0; cnt2<FONT_YSIZE; cnt2++)
		{
			*dcp = *scp;
			scp++;
			dcp += dmod;
		}
	}
}


VOID VT340_setset(struct VT340Console *con, UWORD charset, UWORD G_reg)
{
	con->gset[G_reg] = charset;

	if(con->lset == G_reg)
		VT340_setlset(con, G_reg);

	if(con->rset == G_reg)
		VT340_setrset(con, G_reg);
}


UWORD VT340_cset(struct VT340Console *con, UBYTE c)
{
	switch(c)
	{
		case '5':
			return(DEC_SUPPLEMENTAL);

		case '<':
			return(con->upss);

		case '>':
			return(TECHNICAL);

		case '0':
			return(GRAPHICS);

		case 'A':
			return(ISO_SUPPLEMENTAL);

		case 'B':
		default:
			return(ASCII);
	}
}

/*
#include <hardware/intbits.h>
VOID __saveds __asm CursorServer(register __a1 APTR data)
{
	struct VT340Console *con = (struct VT340Console *)data;
	ULONG col;
	UWORD reg;


	if(con->blink_counter++ == 35)
	{
	/* make text invisible.. */

		reg = (con->ustat & U_REVERSE_VIDEO && con->blink_color == 1) ? 1 : 0;

		col = *con->sv->colors[reg];
		SetRGB4(&(*con->sv->scr)->ViewPort, con->blink_color, (col>>8)&15, (col>>4)&15, col&15);
		return;
	}
	else
		if(con->blink_counter == 70)
		{
		/* make text visible.. */

			reg = (con->ustat & U_REVERSE_VIDEO && con->blink_color == 1)
									 ? 0 : 1;

			col = *con->sv->colors[reg];
			SetRGB4(&(*con->sv->scr)->ViewPort, con->blink_color, (col>>8)&15, (col>>4)&15, col&15);
			con->blink_counter = 0;
		}
}
*/

/*
BOOL VT340_StartCursorInterrupt(struct VT340Console *con)
{
	if(!con->interrupt_started)
	{
		con->cursorhandler.is_Node.ln_Name = "";
		con->cursorhandler.is_Node.ln_Type = NT_INTERRUPT;
		con->cursorhandler.is_Code	= (VOID *)CursorServer;
		con->cursorhandler.is_Data	= (APTR)con;
		AddIntServer(INTB_VERTB, &con->cursorhandler);
		con->interrupt_started = TRUE;
		return(TRUE);
	}
	return(FALSE);
}
*/

/*
BOOL VT340_DeleteCursorInterrupt(struct VT340Console *con)
{
	if(con->interrupt_started)
	{
		RemIntServer(INTB_VERTB, &con->cursorhandler);
		con->interrupt_started = FALSE;
		return(TRUE);
	}
	return(FALSE);
}
*/

/*
VOID VT340_getoldblinkcolor(struct VT340Console *con, UWORD *col, UWORD *reg)
{
	if(con->ustat & U_REVERSE_VIDEO && con->blink_color == 1)
	{
		*reg = 1;
		*col = *con->sv->colors[0];
	}
	else
	{
		*reg = con->blink_color;
		*col = *con->sv->colors[con->blink_color];
	}
}
*/


VOID VT340_resetscreen(struct VT340Console *con, BOOL clearScreen)
{
	UWORD max;

	max = con->io->xem_window->Height >> 3;
	if(max > MAXROWS)
		max = MAXROWS;

	con->statusline = max;
	max--;

	if(con->ustat & U_HOST_STATUSLINE_ACTIVE)
	{
		con->firstline = con->statusline;
		con->lastline	= con->statusline;
		con->row			= con->statusline;
		con->col			= 1;
		con->ysize		= FONT_YSIZE;
	}
	else		/* main screen is active */
	{
		con->firstline	= 1;
		con->lastline	= (con->pstat & P_24LINES) ? 24 : max;

		con->ysize = (con->pstat & P_24LINES  &&  con->pstat & P_ADJUST_LINES)
											? ((max<<3) / con->lastline) : FONT_YSIZE;
	}

	con->columns= 80;
	con->width	= 640;
	con->top		= con->firstline;
	con->bot		= con->lastline;

	if(clearScreen)
	{
		VT340_cursorhome(con);
		VT340_clearactiverowregister(con);
		VT340_eraseactivescreen(con);
		RasterEraseScreen(con, 2);
	}
	else
	{
		VT340_checkdims(con);
	}
}
/*
**VOID VT340_resetscreen(struct VT340Console *con, BOOL clearScreen)
**{
**	UWORD max, height;
**	BOOL eraseScreen;
**
**	if(clearScreen)
**	{
**		if(con->pstat & P_24LINES  &&  con->lastline > 24)
**		{
**			eraseScreen = FALSE;
**			VT340_erasewholescreen(con);
**			con->row = 0;
**			con->col = 0;
**		}
**		else
**			eraseScreen = TRUE;
**	}
**	else
**	{
**		if(con->pstat & P_24LINES  &&  con->lastline > 24)
**		{
**			eraseScreen = FALSE;
**			RasterEraseScreen(con, 0);
**			VT340_eraselines(con, con->row, con->lastline - (con->io->xem_window->Height >> 3));
**		}
**		else
**			eraseScreen = TRUE;
**	}
**
**
**	if(con->ustat & U_HOST_STATUSLINE_ACTIVE)
**	{
**		con->firstline = con->statusline;
**		con->lastline	= con->statusline;
**		con->row			= -1;
**		con->col			= -1;
**	}
**	else		/* main screen is active */
**	{
**		height= con->io->xem_window->Height;
**		max	= con->io->xem_window->Height >> 3;
**
**		if(con->pstat & P_24LINES)
**			con->lastline = 25;
**		else
**			con->lastline = max;
**
**		if(con->lastline > max)
**			con->lastline = max;
**
**		if(con->lastline > MAXROWS)
**			con->lastline = MAXROWS;
**
**		if(con->pstat & P_24LINES  &&  con->pstat & P_ADJUST_LINES)
**			con->ysize = height / con->lastline;
**		else
**			con->ysize = FONT_YSIZE;
**
**		con->statusline = con->lastline;
**		con->lastline--;	/* don't touch possible status-line */
**
**		con->firstline = 1;
**	}
**
**	con->columns= 80;
**	con->width	= 640;
**	con->top		= con->firstline;
**	con->bot		= con->lastline;
**
**	if(clearScreen)
**	{
**		con->row = con->firstline;
**		con->col = 1;
**
**		if(eraseScreen)
**			VT340_eraseactivescreen(con);
**
**		RasterEraseScreen(con, 2);
**	}
**	else
**	{
**		if(con->row < con->firstline)
**			con->row = con->firstline;
**
**		if(con->row > con->lastline)
**			con->row = con->lastline;
**
**
**		if(con->col < 1)
**			con->col = 1;
**
**		if(con->col > con->columns)
**			con->col = con->columns;
**	}
**}
*/

LONG AtoL(UBYTE *str)
{
	LONG cnt=0, help;

	while(*str <= ' ')		/* skip white spaces.. */
	{
		if(*str == '\0')
			return(0);
		str++;
	}

	if(*str == '-')
	{
		help = -1;
		str++;
	}
	else
	{
		if(*str == '+')
			str++;
		help = 1;
	}
	
	for(;;)
	{
		if(*str >= '0' && *str <= '9')
		{
			cnt *= 10;
			cnt += *str - '0';
		}
		else
			break;

		if(!(*str))
			break;

		str++;
	}

	return(cnt * help);
}


#define CHARS 256
#define MODULO CHARS

STATIC BOOL VT340_createfont(struct VT340Console *con)
{
	IMPORT UWORD CharLoc[];
	struct TextFont *dc_font;
	UBYTE *chardata;

	con->dc_font = NULL;
	con->font_remember = NULL;

	dc_font = AllocRemember(&con->font_remember, sizeof(struct TextFont), MEMF_CLEAR | MEMF_PUBLIC);
	chardata = AllocRemember(&con->font_remember, CHARS * FONT_YSIZE, MEMF_CLEAR | MEMF_CHIP | MEMF_PUBLIC);

	if(dc_font  &&  chardata)
	{
		dc_font->tf_Message.mn_Node.ln_Succ	= NULL;
		dc_font->tf_Message.mn_Node.ln_Pred	= NULL;
		dc_font->tf_Message.mn_Node.ln_Type	= NT_FONT;
 		dc_font->tf_Message.mn_Node.ln_Pri	= 0;
		dc_font->tf_Message.mn_Node.ln_Name	= NULL;
		dc_font->tf_Message.mn_ReplyPort		= NULL;
		dc_font->tf_Message.mn_Length			= sizeof(struct TextFont);

		dc_font->tf_YSize			= FONT_YSIZE;
		dc_font->tf_Style			= FS_NORMAL;
		dc_font->tf_Flags			= FPF_DISKFONT;
		dc_font->tf_XSize			= 8;
		dc_font->tf_Baseline		= 6;
		dc_font->tf_BoldSmear	= 1;
		dc_font->tf_Accessors	= 0;
		dc_font->tf_LoChar		= 0;
		dc_font->tf_HiChar		= 255;
		dc_font->tf_CharData		= (APTR)chardata;
		dc_font->tf_Modulo		= MODULO;
		dc_font->tf_CharLoc		= (APTR)CharLoc;
		dc_font->tf_CharSpace	= NULL;
		dc_font->tf_CharKern		= NULL;

		con->dc_font = dc_font;
	}
	else
		FreeRemember(&con->font_remember, TRUE);

	return(con->dc_font != NULL);
}


BOOL VT340_openfonts(struct VT340Console *con)
{
	STATIC BOOL VT340_createfont(struct VT340Console *con);

	struct TextAttr topazattr = { "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };

	IMPORT UBYTE Graphics_Font[];
	IMPORT UBYTE Technical_Font[];
	IMPORT UBYTE ASCII_Font[];
	IMPORT UBYTE DECsuppl_Font[];
	IMPORT UBYTE ISOsuppl_Font[];

	con->fonts[ASCII]					= ASCII_Font;
	con->fonts[DEC_SUPPLEMENTAL]	= DECsuppl_Font;
	con->fonts[ISO_SUPPLEMENTAL]	= ISOsuppl_Font;
	con->fonts[GRAPHICS]				= Graphics_Font;
	con->fonts[TECHNICAL]			= Technical_Font;

	if(con->topazfont = OpenFont(&topazattr))
		return(VT340_createfont(con));
	else
		return(FALSE);
}


VOID VT340_closefonts(struct VT340Console *con)
{
	if(con->dc_font)
	{
		FreeRemember(&con->font_remember, TRUE);
		con->dc_font = NULL;
		con->font_remember = NULL;
	}

	if(con->topazfont)
	{
		CloseFont(con->topazfont);
		con->topazfont = NULL;
	}
}


VOID VT340_createOwnStatusLine(struct VT340Console *con)
{
	if(con->pstat & P_OWN_STATUSLINE  &&  con->statusline)
	{
		auto UBYTE line[88];
		auto UBYTE buf[28];
		UBYTE *opt1, *opt2, *opt3;

		setmem(line, 80L, ' ');

/* */
		if(con->pstat & P_ANSI_MODE)
			opt1 = (con->pstat & P_VT340_MODE) ? " VT-340" : " VT-102";
		else
			opt1 = " VT-52 ";

		strcpy(line, opt1);
/* */

/* */
		opt1 = (con->pstat & P_CONVERT) ? " · 7" : " · 8";
		strcat(line, opt1);
		strcat(line, " BIT · ");
/* */

		strcat(line, "       · ");

/* */
		opt1 = (con->ustat & U_INSERT)	? " INSERT   · "
													: "OVERWRITE · ";
		opt2 = (con->tstat & T_WRAP)		? "  WRAP   · "
													: "TRUNCATE · ";
		opt3 = (con->ustat & U_NEWLINE)	? "NEWLINE "
													: "LINEFEED";

		strcat(line, opt1);
		strcat(line, opt2);
		strcat(line, opt3);
		strcat(line, " · ");
/* */

/* */
		if(con->gstat & G_PRINT_CONTROL)
			opt1 = (con->gstat & G_AUTO_PRINT_INACTIVE) ? "PRINT CTL** · "
																	  : "PRINT CNTRL · ";
		else
		{
			if(con->gstat & G_AUTO_PRINT)
				opt1 = "AUTO PRINT  · ";
			else
				opt1 = "PRINTER OFF · ";
		}

		strcat(line, opt1);
/* */

/* */
		buf[0] = (con->leds & (1<<1)) ? '*' : '.';
		buf[1] = (con->leds & (1<<2)) ? '*' : '.';
		buf[2] = (con->leds & (1<<3)) ? '*' : '.';
		buf[3] = (con->leds & (1<<4)) ? '*' : '.';
		buf[4] = '\0';

		strcat(line, buf);
		if(opt1 = strchr(line, '\0'))
			*opt1 = ' ';
/* */

		SetFont(con->rp, con->topazfont);
		SetDrMd(con->rp, JAM2|INVERSVID);
		SetSoftStyle(con->rp, FS_NORMAL, FSF_UNDERLINED);
		SetBPen(con->rp, BACKGROUND_PEN);
		SetAPen(con->rp, con->foreground_pen);

		Move(con->rp, 0, con->statusline * FONT_YSIZE - (FONT_YSIZE - BOTLINE));
		Text(con->rp, line, 80);

		SetAPen(con->rp, con->apen);
		SetBPen(con->rp, con->bpen);
		SetSoftStyle(con->rp, (UWORD)con->attr, FSF_UNDERLINED);
		SetDrMd(con->rp, JAM2);
		SetFont(con->rp, con->dc_font);

		VT340_locked(con, (con->inDCS  ||  con->inPrivate));
	}
}


VOID VT340_deleteStatusLine(struct VT340Console *con, BOOL ownOnly)
{
	if(con->statusline)
	{
		if(ownOnly)
		{
			if(con->pstat & P_OWN_STATUSLINE)
			{
				VT340_cleararea(con->rp, 0, (con->statusline-1) * FONT_YSIZE, con->width, con->statusline * FONT_YSIZE);
				*(con->rows + con->statusline) = 0;
			}
		}
		else
		{
			VT340_cleararea(con->rp, 0, (con->statusline-1) * FONT_YSIZE, con->width, con->statusline * FONT_YSIZE);
			*(con->rows + con->statusline) = 0;
		}
	}
}


VOID VT340_printdisplay(struct VT340Console *con, BOOL wholeScreen)
{
	UWORD i;
	UBYTE *str;

	if(wholeScreen)
	{
		UBYTE top, bot;

		top = (con->gstat & G_FULLSCREEN) ? con->firstline : con->top;
		bot = (con->gstat & G_FULLSCREEN) ? con->lastline  : con->bot;

		for(i=top-1; i<bot; i++)
		{
			str = &con->text_raster[i * con->raster_width];
			fprintf(con->prt, "%80.80s\r\n", str);
		}
	}
	else
	{
		str = &con->text_raster[(con->row-1) * con->raster_width];
		fprintf(con->prt, "%80.80s\r\n", str);
	}
}


VOID VT340_printterminator(struct VT340Console *con)
{
	UBYTE c;

	c = (con->gstat & G_FORMFEED) ? FF : LF;
	Write(con->prt, &c, 1);
}


BOOL VT340_openprinter(struct VT340Console *con)
{
	if(con->prt == NULL)
	{
		if(con->screen_buf[0] != '\0')
			con->prt = Open(con->screen_buf, MODE_NEWFILE);
	}

	return(con->prt != NULL);
}


VOID VT340_printcontrolled(struct VT340Console *con, UBYTE *buffer, ULONG actual)
{
	UBYTE	*bufpos;

	con->ordc = 0;

	for(bufpos=buffer; bufpos<buffer+actual; bufpos++)
	{
		if(con->ordc == MAXCOLUMNS)
		{
			if(Write(con->prt, con->ordtext, con->ordc) < 0)
			{
				con->gstat &= ~G_PRINT_CONTROL;

				if(con->gstat & G_AUTO_PRINT_INACTIVE)
				{
					con->gstat &= ~G_AUTO_PRINT_INACTIVE;
					con->gstat |=  G_AUTO_PRINT;
				}

				VT340_createOwnStatusLine(con);
			}
			con->ordc = 0;
		}

		if(*bufpos == '\x18'  ||  *bufpos == '\x1A')	/* CAN || SUB */
		{
			con->ESCcmd = FALSE;
			con->CSIcmd = FALSE;
			con->firstarg = 0;
		}


		if(con->ESCcmd)		/* Escape - Befehl ? */
		{
			if(*bufpos == '[')	/* ist's ein verkappter CSI ? */
			{
				con->firstarg = 0;
				con->CSIcmd = TRUE;
				con->ESCcmd = FALSE;
			}
			else
			{
				if(*bufpos >= '0')
					con->ESCcmd = FALSE;
			}
		}


		if(con->CSIcmd)		/* CSI - Befehl ? */
		{
			if(*bufpos >= '0'  &&  *bufpos <= '9')
			{
				con->firstarg = con->firstarg * 10;
				con->firstarg += *bufpos - '0';
			}

			if(*bufpos >= '@')
			{
				UWORD temp = con->firstarg;

				con->firstarg = 0;
				con->CSIcmd = FALSE;

				if(*bufpos == 'i')
				{
					if(temp == 4  &&  con->gstat & G_PRINT_CONTROL)
					{
						*bufpos = '\0';
						con->ordtext[con->ordc++] = CAN;

						if(con->ordc)
						{
							Write(con->prt, con->ordtext, con->ordc);
							con->ordc = 0;
						}

						VT340_printterminator(con);
						con->gstat &= ~G_PRINT_CONTROL;

						if(con->gstat & G_AUTO_PRINT_INACTIVE)
						{
							con->gstat &= ~G_AUTO_PRINT_INACTIVE;
							con->gstat |=  G_AUTO_PRINT;
						}

						VT340_createOwnStatusLine(con);
						continue;
					}
		
					if(temp == 5  &&  VT340_openprinter(con))
					{
						*bufpos = CAN;
						con->ordc = 0;

						con->gstat |= G_PRINT_CONTROL;

						if(con->gstat & G_AUTO_PRINT)
						{
							con->gstat |=  G_AUTO_PRINT_INACTIVE;
							con->gstat &= ~G_AUTO_PRINT;
						}

						VT340_createOwnStatusLine(con);
						continue;
					}
				}
			}
		}


		switch(*bufpos)
		{
			case NUL:
			case XON:
			case XOFF:
				;
			continue;

			case '\033':				/* Escape commands */
				con->ESCcmd = TRUE;
			break;

			case '\233':					/* CSI commands */
				con->firstarg = 0;
				con->CSIcmd = TRUE;
			break;

		}

		if(con->gstat & G_PRINT_CONTROL)
		{
			con->ordtext[con->ordc++] = *bufpos;
			*bufpos = '\0';
		}
	}


	if(con->ordc)
	{
		if(Write(con->prt, con->ordtext, con->ordc) < 0)
		{
			con->gstat &= ~G_PRINT_CONTROL;

			if(con->gstat & G_AUTO_PRINT_INACTIVE)
			{
				con->gstat &= ~G_AUTO_PRINT_INACTIVE;
				con->gstat |=  G_AUTO_PRINT;
			}

			VT340_createOwnStatusLine(con);
		}
		con->ordc = 0;
	}
}


VOID VT340_configopt(struct xem_option *opt, UBYTE *title, UBYTE *buff, UWORD length, BOOL type, BOOL value)
{
	opt->xemo_description= title;
	opt->xemo_value		= buff;
	opt->xemo_type			= type;
	opt->xemo_length		= length;

	if(type == XEMO_BOOLEAN)
	{
		if(value != FALSE)
			strcpy(opt->xemo_value, "on");
		else
			strcpy(opt->xemo_value, "off");

		opt->xemo_length = 4;
	}
}


BOOL VT340_setopt(struct xem_option *opt, UWORD *stat, UWORD val, ULONG changed, ULONG flag)
{
	BOOL chd = FALSE;

	if(changed & (1 << flag))
	{
		chd = TRUE;
		if(!stricmp(opt->xemo_value, "yes") || !stricmp(opt->xemo_value, "on"))
			*stat |= val;
		else
			*stat &= ~val;
	}

	return(chd);
}


VOID VT340_suppdeletechars(struct VT340Console *con, UBYTE cnt)
{
	UWORD y, xsize;

	if(!cnt)
		cnt = 1;

	xsize = XSIZE;
	if(*(con->rows + con->row))
		xsize <<= 1;

	y = con->row * con->ysize;

	if(con->col - 1 + cnt > con->columns)
		cnt = con->columns - con->col + 1;

	RasterScroll_H(con, +cnt, con->row-1, con->col-1);

	ScrollRaster(con->rp, xsize * cnt, 0, (con->col-1) * xsize, y - con->ysize, con->width - 1, y - 1);
}


VOID VT340_clearwholerowregister(struct VT340Console *con)
{
	UWORD i;

	for(i = 0; i <= MAXROWS; i++)
		*(con->rows + i) = 0;
}


VOID VT340_clearactiverowregister(struct VT340Console *con)
{
	UWORD i;

	for(i = con->firstline; i <= con->lastline; i++)
		*(con->rows + i) = 0;
}


VOID VT340_getTopBot(struct VT340Console *con, UWORD *top, UWORD *bot)
{
	if(con->ustat & U_HOST_STATUSLINE_ACTIVE)
	{
		if(top)
			*top = con->statusline;
		if(bot)
			*bot = con->statusline;
	}
	else
	{
		if(top)
			*top = (con->tstat & T_USE_REGION) ? con->top : con->firstline;
		if(bot)
			*bot = (con->tstat & T_USE_REGION) ? con->bot : con->lastline;
	}
}

VOID VT340_checkdims(struct VT340Console *con)
{
	UWORD top, bot;

	VT340_getTopBot(con, &top, &bot);

	if(con->row < top)
		con->row = top;

	if(con->row > bot)
		con->row = bot;

/*******/

	if(con->col < 1)
		con->col = 1;

	if(con->col > con->columns)
		con->col = con->columns;
}


VOID VT340_cursorhome(struct VT340Console *con)
{
	con->row = 0;
	con->col = 0;
	VT340_checkdims(con);
}

/* end of source-code */
