/*
	TECHO.C Ver 0.02 1991.08.09  by Y.Kurihara (Nif PDC01620)"
		T-MENU の画面にちょっかいを出すプログラム  その３

	(1) TECHO [/] [<文字列> ... ]
	(2) TECHO <Ｘ座標> <Ｙ座標> [/] [<文字列> ... ]
	(3) TECHO <Ｘ座標> <Ｙ座標> <桁数> <行数> [/] [<文字列> ... ]

	(1) 文字列を表示する
	(2) 指定位置に文字列を表示する
	(3) 指定範囲に文字列を表示する

	＊文字列の先頭が数字の時は､ '/' を入れることで座標と区別させる｡
	  また、'/' の次に文字列がない時は､ 標準入力を表示する｡
	＊フォントＣＧの使用方法は ORICON (MIYAZAKI氏作) を参考にしました｡
*/

#include <stdio.h>
#include <stdlib.h>
#include <jctype.h>
#include <dos.h>
#include <machine.h>

#define  X0	(2)
#define  Xl	(76)
#define  Y0	(7)
#define  Yl	(20)

#define VRAM( offset )   ( (char far *)MK_FP( 0xc000,( offset ) ) )
#define ANKCG( offset )  ( (char far *)MK_FP( 0xcb00,( offset ) ) )
#define PORTpage   (0xff83)
#define PORTplane  (0xff81)
#define PORTank    (0xff99)
#define PORTkch    (0xff94)	/* 漢字コード */
#define PORTkcl    (0xff95)
#define PORTkfl    (0xff96)	/* 漢字フォント */
#define PORTkfr    (0xff97)
#define Y1page     (16)
#define MAXbuff    (256)

int  lx1,ly1,lx2,ly2,lx,ly;
char buff[ MAXbuff ];

void putank( int code )
{
	unsigned off,add;
	int n;

	if( ly < Y1page ) {
		outp( PORTpage,0x00 );
		off = ly * 16 * 128 + lx;
	} else {
		outp( PORTpage,0x10 );
		off = ( ly - Y1page )* 16 * 128 + lx;
	}
	add = code * 16;
	for( n = 16; --n >= 0;  ) {
		*VRAM( off ) = ~ *ANKCG( add++ );
		off += 128;
	}
	return;
}

void putkan( unsigned code )
{
	int off;
	int n;

	if( ly < Y1page ) {
		outp( PORTpage,0x00 );
		off = ly * 16 * 128 + lx;
	} else {
		outp( PORTpage,0x10 );
		off = ( ly - Y1page )* 16 * 128 + lx;
	}
	code = jmstojis( code );
	outp( PORTkch,code >> 8 );
	outp( PORTkcl,code );
	for( n = 16; --n >= 0;  ) {
		*VRAM( off )     = ~ inp( PORTkfl );
		*VRAM( off + 1 ) = ~ inp( PORTkfr );
		off += 128;
	}
	return;
}

void echo_char( int code )
{
	static int code1 = 0;

	if( code1 ) {			/* 漢字コード */
		if( lx > lx2 - 1 ) {
			lx = lx1;
			ly++;
		}
		if( ly > ly2 )  return;
		putkan( ( code1 << 8 )+ code );
		lx  += 2;
		code1 = 0;
	} else if( iskanji( code ) ) {	/* 漢字コードの1文字目 */
		code1 = code;
	} else if( code >= ' ' ) {	/* 半角文字 */
		if( lx > lx2 ) {
			lx = lx1;
			ly++;
		}
		if( ly > ly2 )  return;
		putank( code );
		lx++;
	} else {			/* 制御コード */
		if( code == '\n' ) {
			lx = lx1;
			ly++;
		}
		if( ly > ly2 )  return;
	}
	return;
}

void echo( unsigned char *str )
{
	int save_page;
	int save_plane;

	save_page  = inp( PORTpage );
	save_plane = inp( PORTplane );
	outp( PORTplane,15 );
	outp( PORTank,1 );

	while( *str ) {
		echo_char( *str++ );
	}

	outp( PORTank,0 );
	outp( PORTpage,  save_page );
	outp( PORTplane, save_plane );
	return;
}

main( int argc,char **argv )
{
	int x1 = X0;
	int y1 = Y0;
	int x2 = Xl;
	int y2 = Yl;

	argv++;
	if( *argv && isdigit( **argv ) )  x1 = atoi( *argv++ );
	if( *argv && isdigit( **argv ) )  y1 = atoi( *argv++ );
	if( *argv && isdigit( **argv ) )  x2 = atoi( *argv++ );
	if( *argv && isdigit( **argv ) )  y2 = atoi( *argv++ );

	if( x1 < 0 || y1 < 0 || x2 < 1 || y2 < 1 )  exit(1);
	if( x1 >= 80 || y1 >= 30 )  exit(1);
	if( ( x2 = x1 + x2 - 1 ) >= 80 )  x2 = 79;
	if( ( y2 = y1 + y2 - 1 ) >= 30 )  y2 = 29;

	lx1 = x1;
	lx2 = x2;
	ly1 = y1;
	ly2 = y2;
	lx = lx1;
	ly = ly1;

	if( *argv == (char *)NULL )  goto Exit;
	if( **argv == '/' ) {
		argv++;
		if( *argv == (char *)NULL )  goto Stdin;
	}
	while( *argv ) {
		echo( *argv++ );
		echo( "\n" );
		if( ly > ly2 )  break;
	}
	goto Exit;
Stdin:
	while( fgets( buff,MAXbuff,stdin ) ) {
		echo( buff );
		if( ly > ly2 )  break;
	}
Exit:
	exit( 0 );
}
