/*
**  M1024.C    by JOUJI
**
**   Ver.1.00  1994.7
**   Ver.1.10  1994.12 プリントファイルの最初の一行を無視しないようにした。
**
**  使い方：m1024 { file_name | /parameter } ...
**
**  '/'で始まる文字列はパラメーターとして扱われる。"$xx"は１６進データ。
*/

#include <stdio.h>
#include <stdlib.h>
#include <jctype.h>

unsigned short _asm_p();

/* ＦＭＲ＆ＴＯＷＮＳ ＢＩＯＳ */
#define bios_asm(x) \
	_asm_p("\n\tINT\t94H\n", 0x100, _asm_p, _asm_p, (char)(x))

void print_file(char *fname);
void print_cc(char *cc);

static char line[256];

main(int argc,char *argv[])
{
	int i;

	if (argc<2) {
		puts("Parameter error !\n");
		exit(1);
	}
	for(i=1; i<argc; i++) {
		if(argv[i][0] == '/') {
			print_cc(argv[i]);
		} else {
			print_file(argv[i]);
		}
	}
}

void bios_print(char c)
{
	char d;
	union {
		unsigned short w;
		struct {
			char l;
			char h;
		} b;
	} ax;

	for(;;) {
		ax.w = bios_asm(c);
		if(!ax.b.h) return;
		if(kbhit()) {
			d = getch();
			if(d == '\x1b' || d == '\x03') exit(2);
		}
	}
}

char hex2char(char *p)
{
	char x, y, c;

	x=0;
	c=toupper(*(p++));
	x = (c>='0' && c<='9') ? c - '0' : c - '7';
	c=toupper(*p);
	y = (c>='0' && c<='9') ? c - '0' : c - '7';
	x=(x << 4) + y;
	return x;
}

void PrintControl(void)
{
	char c, *p;
	int  i;
	FILE  *fq;

	if(line[0] == 0x03) {			/* ^C:コメント */
		return;
	} else if(line[0] == 0x05) {	/* ^E:16進データ */
		for(p = line + 1; *p != '\n'; p += 2) {
			c = hex2char(p);
			bios_print(c);
		}
	} else if(line[0] == 0x06) {	/* ^F:ビット・イメージ・データ・ファイル */
		for(i=1; i<255; i++) {
			if(line[i] == '\n') {
				line[i] = '\0';
				break;
			}
		}
		if( (fq=fopen(&line[1], "rb")) == NULL) {
			puts("File not exist !\n");
			return;
		}
		while((i=fgetc(fq)) != EOF)
			bios_print(i);
		fclose(fq);
	} else if(line[0] == 0x0a) {	/* ^J:空行 */
		bios_print(0x0d);
		bios_print(0x0a);
	} else {
		for(i=0; i<255; i++) {
			c = line[i];
			if(c == '\n' || c == '\0')
				break;
			bios_print(c);
		}
	}
}

void PrintLine(void)
{
	char c, d;
	int  i;
	union {
		unsigned short w;
		struct {
			char l;
			char h;
		} b;
	} sjis, jis;

	for(i=0; i<255; i++) {
		c = line[i];
		if(c == '\n' || c == '\0')
			break;
		if( (c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xff) ) {
			d = line[++i];
			if(d == '\n' || d == '\0') break;
			sjis.b.h = c;
			sjis.b.l = d;
			jis.w = mstojis(sjis.w);
			bios_print(jis.b.h);
			bios_print(jis.b.l);
		} else if(c >= 0x20) {
			bios_print(0);
			bios_print(c);
		} else {
			bios_print(c);
		}
	}
}

void print_file(char *fname)
{
	FILE *fp;

	if( (fp=fopen(fname,"r")) == NULL) {
		puts("File not exist !\n");
		return;
	}
/*	fgets(line, 256, fp); */ /* ファイルの最初の一行無視 */
	while( fgets(line, 256, fp) != NULL) {
		if(line[0] <= 0x1f) {
			PrintControl();
		}
		else {
			PrintLine();
		}
	}
	fclose(fp);
}

void print_cc(char *p)
{
	char c;

	for( p++; *p != '\0'; p++ ) {
		c = *p;
		if( c == '$' ) {
			c = hex2char(++p);
			p++;
		}
		bios_print(c);
	}
}
