/* "pioneer0":ぐいぐいの標準ライブラリ ver.2.2b
    copyright(C) 2002 H.Kawai (川合秀実), I.Tak. */

/* これは、アプリケーションを書きやすくするための各種サービスを提供するプログラム。
   結局のところ、処理をshellcallに取り次いでいるだけ。
   shellcallの仕様は流動的なので、このライブラリがその変化を吸収しているともいえる。 */

/* スタックは1KBくらいあれば問題は無いだろう。 */

segment PioneerMdl(USE32, PARA);
default(code == PioneerMdl);

#if (!defined(TMENU))
	#define DEFAULT_TBOX_BCOL	 8

#else
	#define DEFAULT_TBOX_BCOL	15

#endif

struct WORK { /* 256bytes */
	char signature[8]; int children_back, children_next;
	int softint_EIP, softint_CS, nest /* user用 */, read_ptr /* system用 */;
	int softint_ret_buf[16], softint_mask_buf[16]; /* system用 */
	int signalbox_read_free, signalbox_eos, signalbox_rewind, signaldw /* user用 */;
	int signalbox_write_free, signalbox_write_ptr,
		signalbox_write_ptr0, signalbox_write_ptr1; /* user用 */
	char signalbox_status, ending_count, [14];
	/* 空きは144バイト */
};

struct WINDOW {	/* 128bytes */
	char signature[8];
	int chain_back, chain_next;
	int children_back, children_next;
	int x_size, y_size, x_ofs, y_ofs;
	int slot;
	unsigned char mode0, draw_enable, siglen, sigflag;
	int signalhead[16];
	/* 空きは64バイト */
};

struct TEXTBOX { /* 64bytes */
	char signature[8];
	int chain_back, chain_next;
	int x_size, y_size, x0, y0;
	int option, backcolor, charset, window;
	int blank;
	void [12]; /* 空きは12バイト */
	int buffer[0];
};

struct GRAPHBOX { /* 64bytes */
	char signature[8];
	int chain_back, chain_next;
	int mode, mode_opt, x_bsize, y_bsize; /* バッファ属性(これはユーザーが管理する) */
	int x_vsize, y_vsize, x0, y0; /* 表示上の属性(これもユーザーが管理する) */
	int window, vbuf0, vx0, vy0;
	int buffer[0];
};

void near drawcomponent();
void near drawwindow();
void near textbox_drawback(); /* テキストボックスの背景描画ルーチン */
void near lineconv();

/*
	スロットの使用状況
		0x0000〜0x0170 : shell-call側でリザーブ
		0x01c0〜0x01e0 : システムタイマー
		0x01f0         : pioneerのワークエリア位置などを保存
		0x0200〜0x03f0 : ユーザーに解放
*/

void far pioneer0()
/* Lv3のライブラリー
   セグメントは、DS == FS == SSである事を仮定している。
   コマンドはDS:EBX以降に格納されている。 */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	segment PioneerMdl == CS;

	PUSHAD();
	(offset) cmd = EBX;
	if ((unsigned) cmd[0] != 0x0004) {
		/* 最初のコマンドが初期化コマンドではない */

		EBX = 0xffffffff;
		EAX = 0x0004; /* read user-slot command */
		ECX = 0x01f0; /* スロット番号(pioneerワークスロット) */
		DB(0x9a); DD(0); DW(0x0017); /* shell-call */
		(offset) work = EDX;

		/* softint禁止 */
		LEA(EBX, work->softint_mask_buf[0]); /* add_nest */
	//	work->softint_mask_buf[ 8] = 0xff80; /* (Llv変更しない) */
		(int) [DS:EBX + 8] = 0xff80;
		DB(0x9a); DD(0); DW(0x0017); /* shell-call(softint抑制) */
	}

asmout("nextcmd:");
	EAX = cmd[0];
	if ((unsigned) EAX < 0x0130) {
		TEST(EAX, 0x03);
		if (== 0)
			asmout("JMP DWORD PTR CS:[EAX+#cmd_jumptable]");
	}

	/* コマンド番号エラー
	   EAX    受理されなかったコマンド番号
	   DS:ESI そのコマンドへのポインタ */

cmderr:
	LEA(EBX, work->softint_mask_buf[0]); /* add_nest(Llv変更しない) */
	DB(0x9a); DD(0); DW(0x0017); /* shell-call(softint許可) */
	(int) [SS:ESP + 16 /* EBX */] = (offset) cmd;
INT(0x03); /* コマンドエラーは許さない */
//	TEST(ESP, ESP); // ZF = 0
	POPAD();
	return;

	ALIGN(4);
cmd_jumptable:
	asmout("DD OFFSET cmd000,  OFFSET cmd004,  OFFSET cmd008,  OFFSET cmd00c ");
	asmout("DD OFFSET cmd010,  OFFSET #cmderr, OFFSET cmd018,  OFFSET cmd01c ");
	asmout("DD OFFSET cmd020,  OFFSET cmd024,  OFFSET cmd028,  OFFSET cmd02c ");
	asmout("DD OFFSET cmd030,  OFFSET cmd034,  OFFSET #cmderr, OFFSET cmd03c ");
	asmout("DD OFFSET cmd040,  OFFSET cmd044,  OFFSET cmd048,  OFFSET cmd04c ");
	asmout("DD OFFSET cmd050,  OFFSET cmd054,  OFFSET cmd058,  OFFSET cmd05c ");
	asmout("DD OFFSET cmd060,  OFFSET #cmderr, OFFSET cmd068,  OFFSET #cmderr");
	asmout("DD OFFSET cmd070,  OFFSET cmd074,  OFFSET cmd078,  OFFSET #cmderr");
	asmout("DD OFFSET cmd080,  OFFSET cmd084,  OFFSET #cmderr, OFFSET cmd08c ");
	asmout("DD OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr");
	asmout("DD OFFSET cmd0a0,  OFFSET #cmderr, OFFSET cmd0a8,  OFFSET cmd0ac ");
	asmout("DD OFFSET cmd0b0,  OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr");
	asmout("DD OFFSET cmd0c0,  OFFSET cmd0c4,  OFFSET cmd0c8,  OFFSET #cmderr");
	asmout("DD OFFSET cmd0d0,  OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr");
	asmout("DD OFFSET cmd0e0,  OFFSET cmd0e4,  OFFSET cmd0e8,  OFFSET cmd0ec ");
	asmout("DD OFFSET cmd0f0,  OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr");
	asmout("DD OFFSET #cmderr, OFFSET #cmderr, OFFSET cmd108,  OFFSET cmd10c ");
	asmout("DD OFFSET cmd050,  OFFSET #cmderr, OFFSET cmd118,  OFFSET #cmderr");
	asmout("DD OFFSET cmd120,  OFFSET #cmderr, OFFSET #cmderr, OFFSET #cmderr");
}

void far cmd000()
/* 終了コマンド */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	(int) [SS:ESP + 16 /* EBX */] = (offset) cmd;

	/* 待機中の割り込みを検査 */
	if (work->nest == 0) { /* 割り込みはマスクされていない */
		if (work->signalbox_read_free != 0) { /* バッファにシグナルがある */
			PUSH(EAX); /* ESP -= 4;の代わり */
			if ((unsigned) (int) [SS:ESP + 16 /* ESP */] != 1) {
				/* ハンドラからの帰還要求は出ていない */

				/* 新規割り込み
				   スタックの積み替え

				 <積み替え後のスタック構成>
				   +0 〜  +31 : PUSHADイメージ
				  +32 〜  +43 : EIP, CS, EFLAGS
				  +44 〜  +59 : ES, DS, FS, GS
				  +60 〜  +91 : PUSHADイメージ
				  +92 〜 +103 : EIP, CS, EFLAGS

				   +0 〜  +43は、shellcallルーチンのために用意する
							(読み込まれると取り去られる)
				  +44 〜 +103は、ハンドラが参照するために用意される */

				PUSH(GS);
				PUSH(FS);
				PUSH(DS);
				PUSH(ES);
				PUSHFD();
				ESP -= 40;
				EAX = (int) [SS:ESP +  64]; // EDI
				ECX = (int) [SS:ESP +  68]; // ESI
				EDX = (int) [SS:ESP +  72]; // EBP
				(int) [SS:ESP +  60] = EAX;
				(int) [SS:ESP +  64] = ECX;
				(int) [SS:ESP +  68] = EDX;
				EAX = (int) [SS:ESP +  80]; // EBX
				ECX = (int) [SS:ESP +  84]; // EDX
				EDX = (int) [SS:ESP +  88]; // ECX
				(int) [SS:ESP +  76] = EAX;
				(int) [SS:ESP +  80] = ECX;
				(int) [SS:ESP +  84] = EDX;
				EAX = (int) [SS:ESP +  92]; // EAX
				ECX = (int) [SS:ESP +  96]; // EIP
				EDX = (int) [SS:ESP + 100]; // CS
				(int) [SS:ESP +  88] = EAX;
				(int) [SS:ESP +  92] = ECX;
				(int) [SS:ESP +  96] = EDX;
				EAX = (int) [SS:ESP + 40]; // EFLAGS
				(int) [SS:ESP + 100] = EAX;
			} else {
				/* ハンドラからの帰還要求が出ている */

				/* スタックの上位(+44 〜 +103)は完成している
				   下位(+0 〜 +43)を作り直す */
				EAX = (int) [SS:ESP + 100]; // EFLAGS
				(int) [SS:ESP + 40] = EAX;
			}
			EAX = work->softint_EIP; /* ハンドラへのベクタ */
			ECX = work->softint_CS;
			(int) [SS:ESP + 32] = EAX;
			(int) [SS:ESP + 36] = ECX;
			(int) [SS:ESP + 12] = 2; /* リターン時のLlv */
			work->nest--; /* 割り込んだので、マスクカウントを減少 */
			PUSH(FS);
			LEA(EBX, work->softint_ret_buf[0]);
			work->softint_ret_buf[ 4] = 0;
			work->softint_ret_buf[ 8] = 0x0080; /* 割り込み抑制解除 */
			DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
			INT(0x03); /* エラーが無い限り、ここにはこない */
		}
	}

	/* ハンドラへの分岐はない */
	if ((unsigned) (int) [SS:ESP + 12] == 1) {
		/* 帰還 */
		ESP += 40; /* いらない部分を捨てる(EDI〜EAX, CS:EIP) */
		POP(ES);
		POP(DS);
		POP(EAX); /* FSへ直接ロードせずに、EAXに入れておく */
		POP(GS);
		(int) [SS:ESP + 12] = 2; /* リターン時のLlv */
		PUSH(EAX); /* ここで復帰後のFSを積む */
		LEA(EBX, work->softint_ret_buf[0]);
		work->softint_ret_buf[ 4] = 0;
		work->softint_ret_buf[ 8] = 0x0080; /* 割り込み抑制解除 */
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		INT(0x03); /* エラーが無い限り、ここにはこない */
	}

	/* 何もないので、普通の正常終了 */
	LEA(EBX, work->softint_mask_buf[0]); /* add_nest(Llv変更しない) */
	DB(0x9a); DD(0); DW(0x0017); /* shell-call */
//	(int) [SS:ESP + 16 /* EBX */] = (offset) cmd;
	CMP(EAX, EAX); /* ZF = 1, CF = 0 */
	POPAD();
	return;
}

void near cmd0004_getbECX();
void near cmd0004_getb(); /* CFに返す */
void near cmd0004_decode();
void near cmd0004_decode2();

void far cmd004()
/* pioneer0ライブラリ初期化コマンド */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	/* work初期化(256bytes)
	   optionフィールドをもつ(malloc領域などのため)
	   malloc領域などの設定は、別のコマンドであとからやる。 */
	EAX = cmd[4] /* opt */;
	TEST(AL, 0x03);
	if (!= 0)
		goto special;
	XCHG(EAX, (offset) work);
	(offset) cmd += 8;
	(int) work->signature[0] = 0x6e6f6970 ; /* pion */
	(int) work->signature[4] = 0x30726565 ; /* eer0 */
	LEA(EAX, work->children_back);
	work->children_back = EAX;
	work->children_next = EAX;
	EAX = 0;
//	work->nest = 0xffffffff;
	work->read_ptr = EAX /* 0 */;
	work->softint_ret_buf[ 0] = 0x0208;
	work->softint_ret_buf[12] = EAX /* 0 */;
	work->signalbox_read_free = EAX /* 0 */;
	work->softint_mask_buf[ 0] = 0x0204;
	work->softint_mask_buf[ 4] = EAX /* 0 */;
	work->softint_mask_buf[ 8] = 0xff80;
	work->softint_mask_buf[12] = EAX /* 0x0000 */;
	work->signaldw = EAX /* 0 */;
//	work->signalbox_write_ptr = 0xfffffffe;
	work->ending_count = 0x80; /* bit7:生存フラグ, bit6-0:終了カウント */
	EAX--;
	work->nest = EAX /* 0xffffffff */;
	EAX--;
	work->signalbox_write_ptr = EAX /* 0xfffffffe */;
	/* ベクタ初期化 */
	PUSH(FS);
	PUSH(CS);
	POP(FS);
	asmout("MOV EBX,OFFSET #cmd0004_cmd");
	DB(0x9a); DD(0); DW(0x0017); /* shell-call */
	POP(FS);
	/* slot 0x01f0に(offset) workを書き込み */
	PUSH((int) 0);
	PUSH((offset) work);
	ESP -= 8;
	PUSH((int) 0x01f0); /* slot-no. */
	PUSH((int) 0x0080); /* write user-slot */
	EBX = ESP;
	/* ユーザー割り込み抑制 */
	DB(0x9a); DD(0); DW(0x0017); /* shell-call */
	ESP += 24;
	asmout("JMP nextcmd");

special2:
	EAX = *cmd /* opt */;
	TEST(AL, 0x03);
	asmout("JE nextcmd");
	(offset) cmd -= 4;

special:
	(offset) cmd += 4;
	if (EAX == 0xffffff81) {
		/* opt == 0xffffff81 : l2d3圧縮データー展開 */
		/* cmd, opt(subcmd), bytes, source(48bit), subcmd, ... */
		/* 展開先はES:EDI */
		POP(EDI);
		PUSH(DS);
		PUSH(ESI);
		PUSH(EBP);
		EBP = cmd[4];
		LDS(ESI, [DS:ESI + 8]);
		cmd0004_decode();
		POP(EBP);
		POP(ESI);
		POP(DS);
		PUSH(EDI);
		(offset) cmd += 16;
		goto special2;
	}
	if (EAX == 0xffffff82) {
		/* opt == 0xffffff82 : tek0圧縮データー展開 */
		/* cmd, opt(subcmd), bytes, source(48bit), subcmd, ... */
		/* 展開先はES:EDI */
		POP(EDI);
		PUSH(DS);
		PUSH(ESI);
		PUSH(EBP);
		EBP = cmd[4];
		LDS(ESI, [DS:ESI + 8]);
		cmd0004_decode2();
		POP(EBP);
		POP(ESI);
		POP(DS);
		PUSH(EDI);
		(offset) cmd += 16;
		goto special2;
	}
	if (EAX == 0xffffffff) {
		/* 特別終了 */
		POPAD();
		return;
	}
	INT(0x03);

	ALIGN(4);
cmd0004_cmd:
	asmout("DD 0200H, OFFSET pioneer_softint, 010000C7H, 0201H"); /* softint_vector */
	asmout("DD 0204H, 0, 0281H"); /* to Llv2(nestを80に) */
	asmout("DD 0300H, 01C0H"); /* 獲得(この時、インターバルモードが解除される) */
asmout("cmd004_cmd2:");
	asmout("DD 0310H, 01C0H"); /* 現在時刻設定 */
	asmout("DD 0318H, 01C0H, 0140H, 1, 0080H"); /* メッセージ設定 */
	DD(0x0000);
}

void near cmd0004_getb()
{
	char *src == DS:ESI;

	BL--;
	if ((signed) < 0) {
		BL = 7;
		BH = *src;
		(offset) src++;
	}
	BH <<= 1;
	return;
}

void near cmd0004_getbECX()
{
	char *src == DS:ESI;

	do {
		BL--;
		if ((signed) < 0) {
			BL = 7;
			BH = *src;
			(offset) src++;
		}
		BH <<= 1;
		RCL(EAX, 1);
		ECX--;
	} while (!= 0);
	TEST(EAX, EAX);
	return;
}

void near cmd0004_decode()
/* これはもう主たるデコーダーではないので、多少遅くなってもいいからコンパクトに！ */
{
	char *dst == ES:EDI;

	EBX = 0;
	ECX = 0;
	for (;;) {
		EDX = (offset) &cmd0004_getbECX;
		EAX = 0;
		ECX++;
	//	cmd0004_getbECX(); /* 1bit入力 */
		CALL(EDX);
		if (!= 0) { /* EAX == 1 */
			CL = 8;
		//	cmd0004_getbECX(); /* 8bit入力 */
			CALL(EDX);
			ECX++;
			goto putc;
		}
		CL = 2;
	//	cmd0004_getbECX(); /* 2bit入力 */
		CALL(EDX);
	//	CL = 1;
		if (== 0) {
			CL = 4;
		//	cmd0004_getbECX(); /* 4bit入力 */
			CALL(EDX);
			CL = 4 - 1;
			if (== 0) {
				CL = 8;
			//	cmd0004_getbECX(); /* 8bit入力 */
				CALL(EDX);
				CL = 19 - 1;
				if (== 0) {
					CL = 16;
				//	cmd0004_getbECX(); /* 16bit入力 */
					CALL(EDX);
					if ((unsigned) EAX <= 127) {
						XCHG(EAX, ECX);
						EAX++; /* 最初のbitは1に決まっているから */
					//	cmd0004_getbECX(); /* nbit入力 */
						CALL(EDX);
					}
				}
			}
		}
		/* distanceはmaxで30bit(1GB) */
		EAX += ECX;
		PUSH(EAX);
		EAX = 0;
		EAX--;
		do {
			CL = 4;
		//	cmd0004_getbECX(); /* 4bit入力 */
			CALL(EDX);
			(signed int) EAX >>= 1;
		} while (CF == 1);
		POP(ECX);
		XCHG(EAX, EDX);
		do {
			AL = dst[EDX];
putc:
			*dst = AL;
			(offset) dst++;
			EBP--;
			if (== 0)
				goto fin;
			ECX--;
		} while (!= 0);
	}
fin:
	return;
}

void near cmd0004_getl1a()
/* ECXに返す */
/* ECX = 1で呼ぶこと */
{
//	ECX = 1;
	cmd0004_getb();
	if (CF == 0) {
		do {
			cmd0004_getb();
			RCL(ECX, 1);
			cmd0004_getb();
		} while (CF == 0);
	}
	return;
}

void near cmd0004_getl1b()
/* ECXに返す */
/* ECX = 1で呼ぶこと */
{
//	ECX = 1;
	cmd0004_getb();
	if (CF == 0) {
		do {
			cmd0004_getb();
			RCL(ECX, 1);
			cmd0004_getb();
		} while (CF == 0);
		ECX++;
		return;
	}
	cmd0004_getb();
	ADC(ECX, 0);
	return;
}

#if 0
void near cmd0004_getdf()
/* EAXにstopbits */
/* CF = 0ならリピートマーク検出 */
{
	unsigned int stopbits == EAX, distance == EDX;
	distance = 0xffffffff;
	do {
		do {
			cmd0004_getb();
			RCL(distance, 1);
			stopbits >>= 1;
		} while (CF == 0);
		if (/* stopbits */ == 0)
			break; /* CF == 1 */
		cmd0004_getb();
		if (CF != 0)
			break; /* CF == 1 */
	} while (distance != 0xffffffff); /* 等しいとき、CF == 0, 等しくないとき、CF == 1 */
	return;
}
#endif

void near cmd0004_getl0a()
/* EBPに返す */
/* 進入条件：EBP = 0, ECX = 0 */
{
	do {
		EBP++;
		cmd0004_getb();
		if (CF != 0)
			goto fin;
		EDX--;
	} while (!= 0);
	ECX++; /* ECX = 1; */
	cmd0004_getl1b();
	EBP += ECX;
	ECX = 0;	
fin:
	return;
}

void near cmd0004_decode2()
{
	char *dst == ES:EDI;
	unsigned int *z1 == SS:ESP, *z0 == SS:ESP + 4, *mode == SS:ESP + 8;
	unsigned int *l_ofs == SS:ESP + 12, *dis_s == SS:ESP + 16;
	unsigned int *bytes == SS:ESP + 20;
	EBX = 0;
	ECX = 0;
	EAX = 0;
	PUSH(EBP); /* bytes */
	do {
		CL = 9;
		cmd0004_getbECX(); /* 9bit入力 */
		(unsigned int) EAX >>= 1;
	} while (CF == 0);
	PUSH(EAX); /* dis_s */
	EAX = 0;
	CL = 2;
	cmd0004_getbECX(); /* 2bit入力 */
	PUSH(EAX); /* l_ofs */
	EAX = (offset) &cmd0004_getl1a;
	cmd0004_getb();
	if (CF != 0) {
	//	EAX = (offset) &cmd0004_getl1b;
	//	asmout("ADD EAX,cmd0004_getl1b-cmd0004_getl1a");
		DB(0x83, 0xc0); asmout("DB cmd0004_getl1b-cmd0004_getl1a");
	}
	PUSH(EAX); /* mode */
	LEA(EDX, [ECX + 2]); /* EDX = 2; */
	do {
		EAX = 0;
		CL = 2;
		cmd0004_getbECX(); /* 2bit入力 */
		asmout("MOVSX EAX,BYTE PTR CS:[#table][EAX]");
		PUSH(EAX); /* z0, z1 */
		EDX--;
	} while (!= 0);

	EBP = 0;
	do {
		/* "0"-phase (非圧縮フェーズ) */
		EDX = *z0;
		cmd0004_getl0a(); /* EBPに返す */
		*bytes -= EBP;
		do {
			CL = 8;
			cmd0004_getbECX();
			*dst = AL;
			(offset) dst++;
			EBP--;
		} while (!= 0);
		if (ECX == *bytes)
			break;

		/* "1"-phase (圧縮フェーズ) */
		EDX = *z1;
		cmd0004_getl0a(); /* EBPに返す */
		do {
			/* getdf */
			unsigned int stopbits == EAX, distance == EDX;
		//	distance = 0xffffffff;
			LEA(EDX, [ECX - 1]);
			ECX++; /* l1aやl1bのため */
			stopbits = *dis_s;
			do {
				do {
					cmd0004_getb();
					RCL(distance, 1);
					stopbits >>= 1;
				} while (CF == 0);
				if (/* stopbits */ == 0)
					break;
				cmd0004_getb();
			} while (CF == 0);

			CALL(*mode); /* l1a or l1b */
			ECX += *l_ofs;
			*bytes -= ECX;
			do {
				AL = dst[EDX];
				*dst = AL;
				(offset) dst++;
				ECX--;
			} while (!= 0);
			EBP--;
		} while (!= 0);
	} while (ECX != *bytes);

	ESP += 24;
	return;

table:
	DB(0xff, 4, 8, 16);
}

void near cmd008()
/* pioneer0ライブラリの終了
   オプションで、アプリ自体も終了するか、それともアプリは終了しないかを選べる
   現在は、オプションを確認することもなく、終了 */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	(offset) cmd += 8;
	PUSH((int) 0);
	PUSH((int) 0x0001); // opt(close all handle)
	PUSH((int) 0x0040); /* タスク終了 */
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
	AL = [SS:ESP + 6];
	ESP += 12 - 4;
	AL += work->ending_count;
	AL &= 0x7f;
	work->ending_count = AL;
	if (!= 0) {
		/* sleep */
		LEA(EBX, work->softint_mask_buf[0]); /* add_nest(Llv変更する) */
	//	work->softint_mask_buf[ 8] = 0x0080;
		(int) [DS:EBX + 8] = 0x0080;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		INT(0x03);
	}
//	PUSH((int) 0);
	PUSH((int) 0x0002); // opt(close task)
	PUSH((int) 0x0040); /* タスク終了 */
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
	INT(0x03);
}

void near cmd00c()
/* JMP */
{
	int *cmd == DS:ESI;
	EAX = cmd[4]; /* opt */
	if (EAX == 0) {
		/* 相対ジャンプ */
		(offset) cmd += cmd[8];
		asmout("JMP nextcmd");

	}
	if (EAX == 1) {
		/* 絶対ジャンプ */
		(offset) cmd = cmd[8];
		asmout("JMP nextcmd");
	}
	INT(0x03);
}

void near cmd010()
/* softintベクタ設定 */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EAX = cmd[4] /* EIP */;
	ECX = cmd[8] /* CS */;
	(offset) cmd += 12;
	work->softint_EIP = EAX;
	work->softint_CS = ECX;
	asmout("JMP nextcmd");
}

void near cmd018()
/* wait signal */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EAX = cmd[8]; // signaldw
	EDX = cmd[4]; // opt
	work->signalbox_write_free += EAX;
	work->signalbox_read_free -= EAX;
	if ((unsigned) < 0) {
		/* 書き込んだ以上に、読み込んだと報告された。
		   これは許しがたいエラーである。 */

		INT(0x03); /* エラー処理未完成 */
	}
//	ECX = work->signalbox_write_ptr;
//	TEST(CL, 0x01);
	TEST((char) work->signalbox_write_ptr, 0x01);
	PUSH((int) 0x0000); /* eoc */
	if (!= 0) {
		if (EAX != 0) {
			/* シグナルフルだったので、それを解除 */
			work->signalbox_write_ptr &= 0xfffffffc;
		//	PUSH((int) 0x0000); // eoc
			PUSH((int) 0xff02); // nest
			PUSH((int) 0); // signals
			PUSH((int) 0x0204); // add nest
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
			ESP += 16 - 4;
		}
	}
	if (EDX == 0x0080) {
		/* 帰還要求を表すために、スタック内のESP値を1にする。 */
		(int) [SS:ESP + 12 /* ESP */ + 4] = 1;
	}
	EAX = cmd[12]; // nest
	work->nest += EAX;

	(offset) cmd += 16;
	TEST(EDX, 0xffffff70);
	if (!= 0) {
		// 無効オプション指定
		INT(0x03); // エラー処理未完成
	}

	int slot == EAX;
	slot = 0x01c0;

	TEST(DL, 0x08);
	if (!= 0) {
		// set now time
	//	PUSH((int) 0x0000);
		PUSH((int) /* 0x01c0 */ slot);
		PUSH((int) 0x0310); /* 現在時刻設定 */
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* shell-call */
		ESP += 12 - 4;
	}

	TEST(DL, 0x04);
	if (!= 0) {
		/* add time */
		/* 本来なら最低加算時間のチェックがある */
	//	PUSH((int) 0x0000);
		PUSH(cmd[8]);
		PUSH(cmd[4]);
		PUSH(cmd[0]);
		(offset) cmd += 12;
		PUSH((int) /* 0x01c0 */ slot);
		PUSH((int) 0x0314); /* 時刻加算 */
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24 - 4;
	}

	/* 以下はシグナルが溜まっていないときだけ有効 */
	if (work->signalbox_read_free == 0) {
		TEST(DL, 0x02);
		if (!= 0) {
			// regist timer
		//	PUSH((int) 0x0000);
			PUSH((int) /* 0x01c0 */ slot);
			PUSH((int) 0x0308); /* タイマー登録 */
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // shell-call
			ESP += 12 - 4;
		}
		TEST(DL, 0x01);
		if (!= 0) {
			/* sleep */
			LEA(EBX, work->softint_mask_buf[0]); /* add_nest(Llv変更する) */
			work->softint_mask_buf[ 8] = 0x0080;
			DB(0x9a); DD(0); DW(0x0017); // shell-call

			LEA(EBX, work->softint_mask_buf[0]); /* add_nest(Llv変更しない) */
			work->softint_mask_buf[ 8] = 0xff80;
				/* ライブラリルーチン内に再入したので、割り込みマスク */
			DB(0x9a); DD(0); DW(0x0017); // shell-call
		}
		TEST(DL, 0x02);
		if (!= 0) {
			/* cancel timer */
		//	PUSH((int) 0x0000);
			PUSH((int) /* 0x01c0 */ slot);
			PUSH((int) 0x030c); // タイマー解約
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // shell-call
			ESP += 12 - 4;
		}
	}
	POP(EAX);
	asmout("JMP nextcmd");
}

void near cmd01c()
/* NOP */
{
	int *cmd == DS:ESI;
	(offset) cmd += 4;
	asmout("JMP nextcmd");
}

void near cmd020()
/* create new window.
   slotのbit0 : ユーザーシグナルハンドリング
   slotのbit1 : position offset指定
   今のところ、シグナル長1のみサポート */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	/* WINDOW構造体の初期化など */
	WINDOW *cmd0020_win == DS:EDI;
	(offset) cmd0020_win = cmd[ 4]; // work_ptr
	LEA(EAX, cmd0020_win->children_back); 
	cmd0020_win->children_back = EAX;
	cmd0020_win->children_next = EAX;
	LEA(EAX, cmd0020_win->chain_back);
	ECX = work->children_back;
	work->children_back = EAX;
	(int) [DS:ECX + 4] /* back->next */ = EAX;
	LEA(EAX, work->children_back);
	cmd0020_win->chain_back = ECX;
	cmd0020_win->chain_next = EAX;
	// signatureも初期化しなければいけない

	EAX = cmd[ 8]; // slot-no
	ECX = cmd[12]; // x-size
	EDX = cmd[16]; // y-size
	(offset) cmd += 20;
	TEST(AL, 0x01);
	(int) cmd0020_win->mode0 = 0;
	if (!= 0) {
		/* シグナルハンドリング */
		EBX = cmd[0];
		TEST(BH, 0x01);
		if (!= 0)
			BH ^= 0x10;
		(short) cmd0020_win->siglen = BX;
		/* シグナル長(bit0-3), ハンドリング範囲(bit8-15)
		   値0 : ハンドリングしない
		   bit0 : enable(0)/disable(1)/redraw(2)/redraw2(3)
		   bit1 : move(4)
		   bit2 : setmode(5)
		   bit3 : close(6)
		   bit4 : opt for bit0
		   bit5 : closed(7)
		   bit6 : resize(8)
		   bit7は加算量scale(0はx1、1はx4)
		   残りの4bitはリザーブ
		   最小化はdisableで処理されるので、検知できない
		   clickやresizeは拡張系(8, 9) */
		EBX = cmd[4];
		(offset) cmd += 8;
		cmd0020_win->signalhead[0] = EBX;
	}
	TEST(AL, 0x02);
	if (== 0) {
		ECX += 8 + 8; /* 左右に8dotずつ確保 */
		EDX += 29 + 8; /* 上に29dot、下に8dot確保 */
		cmd0020_win->x_ofs =  8;
		cmd0020_win->y_ofs = 29;
	} else {
		PUSH(EDX);
		EDX = cmd[0]; // x-offset
		EBX = cmd[4]; // y-offset
		(offset) cmd += 8;
		cmd0020_win->x_ofs = EDX;
		cmd0020_win->y_ofs = EBX;
		POP(EDX);
	}
	EAX &= 0xfffffff0;
	cmd0020_win->x_size = ECX;
	cmd0020_win->y_size = EDX;
	cmd0020_win->slot = EAX;
	PUSH((int) 0 /* EOC */);
	PUSH((int) 0x0040 /* signal-base */);
	PUSH((int) 0x0140 /* signalbox(slot番号で指定) */);
	PUSH(EDX /* y-size */);
	PUSH(ECX /* x-size */);
	PUSH((offset) cmd0020_win /* user-no */);
	PUSH(EAX /* slot-no */);
	PUSH((int) 0x0100 /* cmd-no */);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 32;
	asmout("JMP nextcmd");
}

void near cmd024()
/* windowクローズ */
/* これにつながっていた全てのコンポーネントも使えなくなる */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	WINDOW *cmd0024_win == DS:EDI;
	(offset) cmd0024_win = cmd[ 8]; // work_ptr
	(offset) cmd += 12;
	PUSH((int) 0 /* EOC */);
	PUSH(cmd0024_win->slot);
	PUSH((int) 0x0104 /* cmd-no */);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 12;
	work->ending_count++;
	asmout("JMP nextcmd");
}

void near cmd028()
// open text box
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	WINDOW *cmd0028_win == DS:EDI;
	TEXTBOX *cmd0028_textbox == DS:EBX;
	(offset) cmd0028_textbox = cmd[ 8]; // work_ptr
	(offset) cmd0028_win = cmd[32]; // window
	(int) cmd0028_textbox->signature[0] = 0x54584554; // 'TEXT'
	LEA(EAX, cmd0028_textbox->chain_back);
	ECX = cmd0028_win->children_back;
	cmd0028_win->children_back = EAX;
	(int) [DS:ECX + 4] /* back->next */ = EAX;
	LEA(EAX, cmd0028_win->children_back);
	cmd0028_textbox->chain_back = ECX;
	cmd0028_textbox->chain_next = EAX;
	EAX = cmd[ 4]; // opt
	ECX = cmd[12]; // bcolor
	TEST(AL, 0x01);
	if (== 0) {
		ECX = DEFAULT_TBOX_BCOL;
		// titleの時は、アクティブかどうかによって色が変わるので、初期値を設定しない
	}
	cmd0028_textbox->backcolor = ECX;
	EDX = cmd[24]; // x0
	ECX = cmd[28]; // y0
	EDX += cmd0028_win->x_ofs;
	ECX += cmd0028_win->y_ofs;
	TEST(AH, 0xf0);
	if (!= 0) {
		EDX = 24;
		ECX =  4;
	}
	cmd0028_textbox->x0 = EDX;
	cmd0028_textbox->y0 = ECX;
	cmd0028_textbox->option = EAX;
	cmd0028_textbox->window = (offset) cmd0028_win;
	EAX = cmd[16]; // x_size(キャラクター数)
	ECX = cmd[20]; // y_size(キャラクター数)
	cmd0028_textbox->x_size = EAX;
	cmd0028_textbox->y_size = ECX;
	EDX = cmd[36]; // キャラクターセット(slot-no)
	ECX = cmd[40]; // space code.
	(offset) cmd += 44;
	cmd0028_textbox->blank = ECX;

	// バッファの初期化
	cmd0028_textbox->charset = EDX;
	EAX = cmd0028_textbox->x_size;
	PUSH((offset) cmd0028_textbox);
	MUL(cmd0028_textbox->y_size);
	EDX = cmd0028_textbox->backcolor;
	EDX <<= 16;
	(offset) cmd0028_textbox += 64;
	EDX++;
	do {
		(int) [cmd0028_textbox    ] = ECX;
		(int) [cmd0028_textbox + 4] = EDX;
		(offset) cmd0028_textbox += 8;
		EAX--;
	} while (!= 0);
	POP((offset) cmd0028_textbox);

	if (AL != cmd0028_win->draw_enable) { // AL == 0
		/* もし、描画フラグが1なら、更新する(フレームを描くとか、背景色をセットするとか)。 */
		EAX = cmd0028_textbox->option;
		TEST(AH, 0xf0);
		if (== 0) {
			TEST(AL, 0x01);
			if (!= 0) {
				EDX = cmd0028_win->slot;
				PUSH(ESI);
				ESI = (offset) cmd0028_textbox;
				// EDX:win_slot, ESI:textbox
				EAX = 0x0020;
				textbox_drawback();
				POP(ESI);
			}
		}
	}
	asmout("JMP nextcmd");
}

void near cmd02c()
/* close text box */
/* cmd, opt, textbox */
{
	int *cmd == DS:ESI;
	WINDOW *win == DS:EDI;
	TEXTBOX *textbox == DS:EBX;
	(offset) textbox = cmd[8];
	(offset) cmd += 12;

	int *back == DS:EAX, *next == DS:ECX;
	(offset) back = textbox->chain_back;
	(offset) next = textbox->chain_next;
	(offset) win = textbox->window;
	back[4 /* next */] = (offset) next;
	next[0 /* back */] = (offset) back;

	EAX = 0;
	if (AL != win->draw_enable) {
		/* もし描画フラグが1なら、消去する。 */
		PUSH(EAX);
		EAX = textbox->x0;
		ECX = textbox->y0;
		EDX = textbox->option;
		PUSH((int) 8);
		PUSH(EDX);
		PUSH(EDX);
		PUSH(ECX);
		PUSH(EAX);
		EAX = textbox->x_size;
		ECX = textbox->y_size;
		EAX *= 8;
		ECX *= 8;
		TEST(DL, 0x10);
		if (== 0)
			ECX *= 2;
		EAX += textbox->x0;
		ECX += textbox->y0;
		EAX--;
		ECX--;
		TEST(DL, 0x01);
		(int) [SS:ESP +  8] = EAX;
		(int) [SS:ESP + 12] = ECX;
		if (!= 0) {
			EAX += 3;
			ECX += 3;
			(int) [SS:ESP +  8] = EAX;
			(int) [SS:ESP + 12] = ECX;
			(int) [SS:ESP     ] -= 3;
			(int) [SS:ESP +  4] -= 3;
		}
		PUSH(win->slot);
		PUSH((int) 0x0020 /* boxfill */);
		PUSH((int) 0x0400 /* line cmd */);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 36;
	}
	asmout("JMP nextcmd");
}

void near cmd030()
// open graphic box
/* cmd, opt(0), graphbox */
/* cmd, opt(1), graphbox, mode, mode_opt, x_size, y_size, x0, y0, window */
/* cmd, opt(2), graphbox, mode, mode_opt, x_bsize, y_bsize,
	x_vsize, y_vsize, x0, y0, window */

/* optのbit15が1ならGAPIへコマンドは送らない */
/* optのbit12が1なら、バッファの初期化はしない */
/* 別のコマンドで、グラフィックコマンドの表示位置を設定する(controlgbox) */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	WINDOW *win == DS:EDI;
	GRAPHBOX *graphbox == DS:EBX;

	EAX = cmd[ 4]; // opt
	(offset) graphbox = cmd[ 8]; // work_ptr
	if (AL == 0x01) {
		(offset) win = cmd[36]; // window
		EAX = cmd[12]; // mode
		ECX = cmd[16]; // mode_opt
		EDX = cmd[20]; // x_size
		graphbox->mode = EAX;
		graphbox->mode_opt = ECX;
		graphbox->x_bsize = EDX;
		graphbox->x_vsize = EDX;
		EAX = cmd[24]; // y_size
		ECX = cmd[28]; // x0
		EDX = cmd[32]; // y0
		ECX += win->x_ofs;
		EDX += win->y_ofs;
		graphbox->y_bsize = EAX;
		graphbox->y_vsize = EAX;
		graphbox->x0 = ECX;
		graphbox->y0 = EDX;
		LEA(EAX, graphbox->buffer[0]);
		ECX = 0;
		PUSH((int) 40);
		graphbox->vbuf0 = EAX;
		graphbox->vx0 = ECX;
		graphbox->vy0 = ECX;
		graphbox->window = (offset) win;
		/* 以下はmode:01を仮定 */
		AL = cmd[5];
		TEST(AL, 0x10);
		if (== 0) {
			EAX = graphbox->x_bsize;
			MUL(graphbox->y_bsize);
			EDX = graphbox->vbuf0;
			ECX = graphbox->mode_opt;
			do {
				[DS:EDX] = CL;
				EDX++;
				EAX--;
			} while (!= 0);
		}
	} else if (AL == 0x02) {
		(offset) win = cmd[44]; // window
		EAX = cmd[12]; // mode
		ECX = cmd[16]; // mode_opt
		EDX = cmd[20]; // x_bsize
		graphbox->mode = EAX;
		graphbox->mode_opt = ECX;
		graphbox->x_bsize = EDX;
		EAX = cmd[24]; // y_bsize
		ECX = cmd[28]; // x_vsize
		EDX = cmd[32]; // y_vsize
		graphbox->y_bsize = EAX;
		graphbox->x_vsize = ECX;
		graphbox->y_vsize = EDX;
		EAX = cmd[36]; // x0
		ECX = cmd[40]; // y0
		EAX += win->x_ofs;
		ECX += win->y_ofs;
		graphbox->x0 = EAX;
		graphbox->y0 = ECX;
		ECX = 0;
		LEA(EAX, graphbox->buffer[0]);
		PUSH((int) 48);
		graphbox->vbuf0 = EAX;
		graphbox->vx0 = ECX;
		graphbox->vy0 = ECX;
		graphbox->window = (offset) win;
		/* 以下はmode:01を仮定 */
		AL = cmd[5];
		TEST(AL, 0x10);
		if (== 0) {
			EAX = graphbox->x_bsize;
			MUL(graphbox->y_bsize);

			EDX = graphbox->vbuf0;
			ECX = graphbox->mode_opt;
			do {
				[DS:EDX] = CL;
				EDX++;
				EAX--;
			} while (!= 0);
		}
	} else {
		PUSH((int) 12);
		(offset) win = graphbox->window;
	}
	(offset) win = graphbox->window; // window
	(int) graphbox->signature[0] = 0x50415247; // 'GRAP'
	LEA(EAX, graphbox->chain_back);
	ECX = win->children_back;
	win->children_back = EAX;
	(int) [DS:ECX + 4] /* back->next */ = EAX;
	LEA(EAX, win->children_back);
	graphbox->chain_back = ECX;
	graphbox->chain_next = EAX;

	if (win->draw_enable != 0) {
		/* 必要ならフレームを描く */
		AL = cmd[ 5];
		TEST(AL, 0x80);
		if (== 0) {
			EAX = graphbox->x_bsize;
			PUSH((int) 0);
			EAX -= graphbox->x_vsize;
			PUSH(DS);
			PUSH(graphbox->vbuf0);
			PUSH(EAX);
			PUSH(graphbox->y_vsize);
			PUSH(graphbox->x_vsize);
			PUSH(graphbox->y0);
			PUSH(graphbox->x0);
			PUSH(win->slot);
			PUSH(graphbox->mode);
			PUSH((int) 0x0414);
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
			ESP += 44;
		}
	}
	POP(EAX);
	(offset) cmd += EAX;
	asmout("JMP nextcmd");
}

void near cmd034()
/* close graphic box */
/* cmd, opt, graphicbox */
{
	INT(0x03);
}

void near cmd040()
// put string
/* bit0 : bcolor */
/* bit1 : color-font */
/* bit6 : far-ptr */
{
	int *cmd == DS:ESI;
	WINDOW *win == DS:EDI;
	TEXTBOX *textbox == DS:EBX;
	TEXTBOX *textbox2 == DS:ECX;

	PUSH(ES);
	PUSH(DS);
	(offset) textbox = cmd[16];
	EAX = cmd[12]; // y_pos
	POP(ES);
	EDI = cmd[ 8]; // x_pos
	MUL(textbox->x_size);
	PUSH(EBP);
	ESP -= 52;
	EAX += EDI; // x_pos
	EBP = ESP;
	EDX = cmd[12]; // y_pos
	ECX = textbox->option;
	EDX *= 8;
	EDI *= 8;
	TEST(CL, 0x10); // option
	if (== 0)
		EDX *= 2;
	EDI += textbox->x0;
	EDX += textbox->y0;
	(int) [SS:EBP + 12] = EDI; /* x0 */
	(int) [SS:EBP + 16] = EDX; /* y0 */
	EDI = textbox->charset;
	(int) [SS:EBP +  4] = 0x3000; /* option */
	(int) [SS:EBP + 28] = EDI; /* charset */
	(offset) win = textbox->window;
	EDX = textbox->backcolor;
	PUSH((offset) textbox);
	LEA(EBX, [(offset) textbox + EAX * 8 + 64]); /* これ以降textboxは使えない */
	EAX = cmd[ 4]; /* option */
	TEST(AL, 0x01);
	if (!= 0)
		EDX = cmd[24]; // back_color
	TEST(CL, 0x10); /* half height */
	if (!= 0)
		(char) [SS:EBP +  4] = 0x01; /* option */
	TEST(CH, 0xf0);
	ECX = cmd[20]; /* color */
	if (!= 0) {
		/* to wintitle */
		PUSH(EAX);
		EAX = win->mode0;
	//	(int) [SS:EBP + 12] = 24; /* x0 */
	//	(int) [SS:EBP + 16] =  4; /* y0 */
		asmout("MOVZX ECX,WORD PTR CS:[EAX*2+wintitle_colortable]");
		POP(EAX);
		EDX = ECX;
		ECX &= 0x7f;
		EDX /= 256;
	}
	(int) [SS:EBP + 20] = ECX; /* color */
	(int) [SS:EBP + 24] = EDX; /* backcolor */
	EDX <<= 16;
	(int) [SS:EBP +  0] = 0x0404;
	EDX |= ECX;
	ECX = win->slot;
	(int) [SS:EBP + 40] = EBX;
	(int) [SS:EBP +  8] = ECX; /* slot */
	ECX = 0;
	(short) [SS:EBP + 44] = DS;
	(int) [SS:EBP + 32] = ECX; // 0; /* base */
	(int) [SS:EBP + 48] = ECX; // 0; /* eoc */
	PUSH(EDI);
	(offset) cmd += 32;
	TEST(AL, 0x02);
	if (!= 0) {
		/* color font */
		(char) [SS:EBP +  4] |= 0x02; /* option */
	}
	PUSH(EBP);
	TEST(AH, 0x30);
	PUSH(EAX);
	if (!= 0) {
		ECX = cmd[-4];
		(offset) cmd += 4;
	}
	TEST(AH, 0x40);
	EBP = cmd[-4]; // length
	EDI = (offset) cmd;
	(int) [SS:ESP + 16 + 36] = EBP; // length
	if (!= 0) {
		asmout("LES EDI,[ESI]");
		(offset) cmd += 8;
	}
	TEST(AL, 0x02);
	if (!= 0)
		goto skip;
	if (EDX == 0)
		goto blank;
skip:
	AH &= 0x30;
	if (== 0)
		goto opt00;
	if (AH == 0x10) {
		do {
			EAX = (unsigned char) [ES:EDI];
			EDI++;
			EAX += ECX;
			[DS:EBX + 4] = EDX;
			[DS:EBX + 0] = EAX;
			EBX += 8;
			EBP--;
		} while (!= 0);
	} else if (AH == 0x20) {
		do {
			EAX = (unsigned short) [ES:EDI];
			EDI += 2;
			EAX += ECX;
			[DS:EBX + 4] = EDX;
			[DS:EBX + 0] = EAX;
			EBX += 8;
			EBP--;
		} while (!= 0);
	} else {
opt00:
		do {
			EAX = (unsigned int) [ES:EDI];
			EDI += 4;
			EAX += ECX;
			[DS:EBX + 4] = EDX;
			[DS:EBX + 0] = EAX;
			EBX += 8;
			EBP--;
		} while (!= 0);
	}
	
skip2:
	EDI += 3;
	POP(EAX);
	EDI &= 0xfffffffc;
	TEST(AH, 0x40);
	POP(EBX); /* == EBP */
	if (== 0)
		ESI = EDI;
	POP(EDI);
	if (win->draw_enable != 0) {
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	}
	ESP += 4 + 52;
	POP(EBP);
	POP(ES);
	asmout("JMP nextcmd");

blank:
	(offset) textbox2 = [SS:ESP + 12];
	EDX++;
	AH &= 0x30;
	ECX = textbox2->blank;
	if (== 0)
		goto blank_d;
	if (AH == 0x10)
		goto blank_b;
	if (AH == 0x30) {
blank_d:
		EBP *= 2;
	}
	EBP *= 2;
blank_b:
	EDI += EBP;
	do {
		[DS:EBX + 0] = ECX;
		[DS:EBX + 4] = EDX;
		EBX += 8;
		EBP--;
	} while (!= 0);
	goto skip2;

	ALIGN(2);
	#if (!defined(TMENU))
		asmout("wintitle_colortable DW 0008H, 0708H, 0, 040FH");
	#else
		asmout("wintitle_colortable  DW 0f07H, 0800H, 0, 000fH");
		asmout("wintitle_colortable2 DW 000fH, 0008H, 0, 000cH");
	#endif
}

void near cmd044()
// line & box (without graphicbox)
// windowを指定した場合、enableのチェックはしないので要注意

//  +00 : cmd
//  +04 : opt
//  +08 : 0(window)
//  +0c : color
//  +10 : x0
//  +14 : y0
//  +18 : x1
//  +1c : y1
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	WINDOW *win == DS:EBX;

	PUSH(EBP);
	EDI = 0;
	PUSH(EDI); /* eoc */
	ESP -= 36 - 4;
	EAX = cmd[ 4]; // opt
	EBP = ESP;
	(offset) win = cmd[ 8]; // window
	ECX = cmd[12]; // color
	EDX = EDI;
	if ((unsigned) (offset) win != 0xffffffff) {
		EDX = win->slot;
	}
	(int) [SS:EBP +  0] = 0x0400; // cmd
	(int) [SS:EBP +  4] = EAX; // opt
	(int) [SS:EBP +  8] = EDX; // slot
	(int) [SS:EBP + 28] = ECX; // color
	EDX = EDI;
	if ((unsigned) (offset) win != 0xffffffff) {
		EDX = win->x_ofs;
		EDI = win->y_ofs;
	}
	EAX = cmd[16]; // x0
	ECX = cmd[20]; // y0
	EAX += EDX;
	ECX += EDI;
	(int) [SS:EBP + 12] = EAX; // x0
	(int) [SS:EBP + 16] = ECX; // y0
	EAX = cmd[24]; // x1
	ECX = cmd[28]; // y1
	EAX += EDX;
	ECX += EDI;
	(offset) cmd += 32;
	(int) [SS:EBP + 20] = EAX; // x1
	(int) [SS:EBP + 24] = ECX; // y1
//	(int) [SS:EBP + 32] = 0; // eoc
	EBX = EBP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 36;
	POP(EBP);
	asmout("JMP nextcmd");
}

void near cmd048()
// put string(without textbox)
// windowを指定した場合、enableのチェックはしないので要注意

// +00 : cmd
// +04 : opt(bit0:backcolor-enableは無視、常にenable)
// +08 : -1/window
// +12 : charset
// +16 : x_pos(dot)
// +20 : y_pos(dot)
// +24 : color
// +28 : backcolor
// +32 : length

// optのbit0は調べていない。1だという前提。
/* int-base0以外は未対応 */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	WINDOW *win == DS:EBX;

	PUSH(EBP);
	EAX = 0;
	ESP -= 52;
	(offset) win = cmd[ 8];
	EBP = ESP;
	ECX = EAX;
	EDX = EAX;
	if ((unsigned) (offset) win != 0xffffffff) {
		EAX = win->slot;
		ECX = win->x_ofs;
		EDX = win->y_ofs;
	}
	ECX += cmd[16]; // x_pos(dot)
	EDX += cmd[20]; // y_pos(dot)
	(int) [SS:EBP     ] = 0x0404; /* put text */
	(int) [SS:EBP +  4] = 0x0000; /* option */
	(int) [SS:EBP +  8] = EAX;
	(int) [SS:EBP + 12] = ECX; /* x0 */
	(int) [SS:EBP + 16] = EDX; /* y0 */
	EAX = cmd[24]; // color
	ECX = cmd[28]; // backcolor
	EDX = cmd[12]; // charset
	(int) [SS:EBP + 20] = EAX; // color
	(int) [SS:EBP + 24] = ECX; /* backcolor */
	(int) [SS:EBP + 28] = EDX; // charset
	ECX = cmd[32]; // length
	(offset) cmd += 36;
	EAX = 0;
	(int) [SS:EBP + 32] = EAX; /* base */
	(int) [SS:EBP + 36] = ECX; // length
	(int) [SS:EBP + 40] = (offset) cmd;
	[SS:ESP + 44] = DS;
	(int) [SS:EBP + 48] = EAX; /* eoc */
	LEA(ESI, [ESI + ECX * 4]);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 52;
	POP(EBP);
	asmout("JMP nextcmd");
}

void near cmd04c()
/* ブロック転送 */
/* cmd, opt(1), window, x0, y0, xsize, ysize, yskip, ofs, sel */
/* windowを指定した場合、enableのチェックはしないので要注意 */
/* optのbit15を1にすると、enableのチェックをするようになる */
{
	int *cmd == DS:ESI;
	WINDOW *win == DS:ECX;

	EAX = cmd[ 4];
	(offset) win = cmd[ 8];
	EDX = 0;
	EBX = cmd[12];
	EDI = cmd[16];
	if ((unsigned) (offset) win == 0xffffffff) /* 常にイネーブルとみなす */
		goto draw;
	EBX += win->x_ofs;
	EDI += win->y_ofs;
	CMP(win->draw_enable, 0);
	EDX = win->slot;
	if (!= 0)
		goto draw;
	TEST(EAX, 0x80008000);
	if (== 0) {
draw:
		EAX &= 0x7fff7fff;
		PUSH((int) 0);
		PUSH(cmd[36]);
		PUSH(cmd[32]);
		PUSH(cmd[28]);
		PUSH(cmd[24]);
		PUSH(cmd[20]);
		PUSH(EDI);
		PUSH(EBX);
		PUSH(EDX);
		PUSH(EAX);
		PUSH((int) 0x0414);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 44;
	}
	(offset) cmd += 40;
	asmout("JMP nextcmd");
}

void near cmd050()
// points (window)
/* cmd, opt, window, x0, y0, xsize, ysize, points, ofs, sel */
/* optのbit15を1にすると、windowがアクティブの時しか書き込まない */

// lines (window)
/* cmd, opt, window, x0, y0, xsize, ysize, lines, ofs, sel */
/* 変換処理はcmd10cで行う */
/* optのbit15を1にすると、ウィンドウライトディゼーブルのときは書き込まない */
{
	int *cmd == DS:ESI;
	WINDOW *win == DS:ECX;

	EBX = 0x0418; /* lines */
	if (EAX == 0x050)
		EBX += 4; /* EBX = 0x041c; */ /* points */

	EAX = cmd[ 4];
	PUSH(EBP);
	(offset) win = cmd[ 8];
	EDX = 0;
	EBP = cmd[12];
	EDI = cmd[16];
	if ((unsigned) (offset) win == 0xffffffff) /* 常にイネーブルとみなす */
		goto draw;
	EBP += win->x_ofs;
	EDI += win->y_ofs;
	CMP(win->draw_enable, 0);
	EDX = win->slot;
	if (!= 0)
		goto draw;
	TEST(AH, 0x80);
	if (== 0) {
draw:
		AH &= 0x7f;
		PUSH((int) 0x0000);
		PUSH(cmd[36]);
		PUSH(cmd[32]);
		PUSH(cmd[28]); /* points */
		PUSH(cmd[24]); /* ysize */
		PUSH(cmd[20]); /* xsize */
		PUSH(EDI);
		PUSH(EBP);
		PUSH(EDX);
		PUSH(EAX); /* opt */
		PUSH(EBX); /* cmd */
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 44;
	}
	POP(EBP);
	(offset) cmd += 40;
	asmout("JMP nextcmd");
}

void near cmd108_sub();

void near cmd054()
// line & box (graphicbox)

//  +00 : cmd
//  +04 : opt
//  +08 : 0(window)
//  +0c : color
//  +10 : x0
//  +14 : y0
//  +18 : x1
//  +1c : y1
/* optのbit15を1にすると、グラフィックボックスバッファにしか書き込まない */
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	WINDOW *win == SS:EBP;
	GRAPHBOX *gbox == DS:EDI;

	EAX = cmd[ 4];
	EAX &= 0x0030;
	if (== 0) {
		/* line */
		PUSH(EBP);
		EDX = cmd[16];
		EBX = cmd[20];
		EAX = cmd[24];
		ECX = cmd[28];
		lineconv();
		EBP++;
		PUSH(cmd[12]);
		PUSH(EBP);
		PUSH(ECX);
		PUSH(EAX);
		PUSH(EBX);
		EAX = cmd[ 4];
		PUSH(EDX);
		ECX = 0;
		EDI = ESP; /* ES == SSを仮定 */
		PUSH((offset) cmd);
		ECX++;
		ESI = cmd[ 8];
		EDX = 0;
		EBX = 0;
		cmd108_sub();
		POP((offset) cmd);
		(offset) gbox = cmd[ 8];
		(offset) win = gbox->window;
		TEST(AH, 0x80);
		if (== 0) {
			if (win->draw_enable != 0) {
				EAX = ESP;
				PUSH((int) 0x0000);
				PUSH(SS);
				PUSH(EAX);
				PUSH(ECX); /* lines(1) */
				EAX = cmd[16];
				ECX = cmd[20];
				EDX = cmd[24];
				EBX = cmd[28];
				if (EAX > EDX)
					XCHG(EAX, EDX);
				if (ECX > EBX)
					XCHG(ECX, EBX);
				EDX++;
				EBX++;
				EDX -= EAX;
				EBX -= ECX;
				EAX -= gbox->vx0;
				ECX -= gbox->vy0;
				(short) [SS:ESP + 18] -= AX;
				(short) [SS:ESP + 22] -= CX;
				EAX += gbox->x0;
				ECX += gbox->y0;
				PUSH(EBX);
				PUSH(EDX);
				PUSH(ECX);
				PUSH(EAX);
				PUSH(win->slot);
				PUSH(cmd[ 4]); /* opt */
				PUSH((int) 0x0418); /* linear dots */
				EBX = ESP;
				DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
				ESP += 44;
			}
		}
		ESP += 24;
		POP(EBP);
		(offset) cmd += 32;
		asmout("JMP nextcmd");
	}
	INT(0x03);
}

void near cmd058()
/* putblock (gbox)
	cmd, opt, gbox, x0, y0, x_size, y_size, buf, buf_skip, (tbuf, tbuf_skip, tcol0)
  optはグラフィックボックス、バッファのタイプを示す。共通でなければならない。
  optのbit4が1なら、bufは透明色を有する(bcol0がある)。
  optのbit12が1なら、差分を生成(tbuf以下の3dwが存在する)。
  optのbit13が1なら、グラフィックボックスへの転送を抑制(x0〜y_size, xsz_bufはない)。
		代わりに、vx0, vy0がある。
  optのbit15を1にすれば、GAPIは呼ばない。
  0x0001 : 普通のgboxへのputblock
  0x1001 : 差分生成付きのputblock(必要なければ差分は作らない)
  0x2001 : グラフィックボックスの内容は更新しないで、スクロール扱い。GAPIヘフラッシュ。
  0x3001 : 差分生成して、差分だけGAPIへ、スクロール扱い(必要なければ差分は作らない)。
  0x8001 : GAPIへの転送無し
  0x9001 : GAPIへの転送無し(差分)
  0xa001 : 何もしない、単なるスクロール
  0xb001 : 差分を生成。GAPIやグラフィックボックスへの更新はない、スクロールはしない(注意!)。
  とりあえず、0x2001と0x3001だけを作る。

	0x0058, 0x3001, gbox, buf, vx0, vy0, tbuf, tbuf_skip, tcol0 (gboxとbufはオーバーラップしてもいい)
	0x0058, 0x2001, gbox, buf, vx0, vy0
*/
{
	int *cmd == DS:ESI;
	GRAPHBOX *gbox == DS:EDI;
	WINDOW *win == SS:EBP;

	EAX = cmd[ 4];
	if (EAX == 0x3001) {
		PUSH(EBP);
		(offset) gbox = cmd[ 8];
		EBX = cmd[12]; /* buf */
		EDX = gbox->vbuf0;
		EAX = cmd[16]; /* vx0 */
		ECX = cmd[20]; /* vy0 */
		(offset) win = gbox->window;
		gbox->vbuf0 = EBX;
		gbox->vx0 = EAX;
		gbox->vy0 = ECX;
		if (win->draw_enable != 0) {
			ECX = gbox->x_bsize;
			PUSH((offset) cmd);
			ECX -= gbox->x_vsize;
			AH = cmd[32]; /* tcol0 */
			PUSH(cmd[28] /* tbuf_skip */);
			ESI = cmd[24]; /* tbuf */
			PUSH(ECX);

			/* EDXとEBXを比較して、ESIへ */

			EBP = gbox->y_vsize;
			do {
				unsigned char *old == DS:EDX, *new == DS:EBX, *delta == DS:ESI;
				ECX = gbox->x_vsize;
				do {
					AL = *new;
					(offset) new++;
					if (AL == *old)
						AL = AH; /* ここはCMOVEが使える */
					(offset) old++;
					*delta = AL;
					(offset) delta++;
					ECX--;
				} while (!= 0);
				(offset) new   += [SS:ESP + 0];
				(offset) old   += [SS:ESP + 0];
				(offset) delta += [SS:ESP + 4];
				EBP--;
			} while (!= 0);

			POP(ECX);
			POP(EAX);
			(offset) win = gbox->window;
			POP((offset) cmd);

			/* 差分転送コマンドを発行 */

			PUSH((int) 0);
			PUSH(cmd[32]); /* 透明色 */
			PUSH(DS);
			PUSH(cmd[24]); /* tbuf */
			PUSH(cmd[28]); /* skip */
			PUSH(gbox->y_vsize);
			PUSH(gbox->x_vsize);
			PUSH(gbox->y0);
			PUSH(gbox->x0);
			PUSH(win->slot);
			PUSH((int) 0x0011);
			PUSH((int) 0x0414);
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
			ESP += 48;
		}
		(offset) cmd += 36;
		POP(EBP);
		asmout("JMP nextcmd");
	} else if (EAX == 0x2001) {
		WINDOW *winEDX == DS:EDX;
		(offset) gbox = cmd[ 8];
		EBX = cmd[12]; /* buf */
		EAX = cmd[16]; /* vx0 */
		ECX = cmd[20]; /* vy0 */
		(offset) winEDX = gbox->window;
		gbox->vbuf0 = EBX;
		gbox->vx0 = EAX;
		gbox->vy0 = ECX;
		if (winEDX->draw_enable != 0) {
			EAX = gbox->x_bsize;
			ECX = gbox->x_vsize;
			PUSH((int) 0);
			EAX -= ECX;
			PUSH(DS);
			PUSH(EBX); /* buf */
			PUSH(EAX); /* skip */
			PUSH(gbox->y_vsize);
			PUSH(gbox->x_vsize);
			PUSH(gbox->y0);
			PUSH(gbox->x0);
			PUSH(winEDX->slot);
			PUSH((int) 0x0001);
			PUSH((int) 0x0414);
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
			ESP += 44;
		}
		(offset) cmd += 24;
		asmout("JMP nextcmd");
	}
	INT(0x03);
}

void near cmd05c_sub()
/* EAX == opt, points == ECX, dat == ES:EDI, gbox == DS:ESI */
/* EDX == x0, EBX == y0 */
{
	GRAPHBOX *gbox == DS:ESI;

	PUSHAD();
	EAX >>= 6;
	EAX &= 0x03;
	if (== 0) { /* pset */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			AL = [ES:EDI + 8]; /* color */
			EBX += [ES:EDI + 4];
			EDX += [ES:EDI + 0];
			IMUL(EBX, gbox->x_bsize);
			EDI += 12;
			EDX += EBX;
			(char) [DS:ESI + EDX + 64] = AL;
			ECX--;
		} while (!= 0);
		POPAD();
		return;
	}
	if (EAX == 1) { /* and */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			AL = [ES:EDI + 8]; /* color */
			EBX += [ES:EDI + 4];
			EDX += [ES:EDI + 0];
			IMUL(EBX, gbox->x_bsize);
			EDI += 12;
			EDX += EBX;
			(char) [DS:ESI + EDX + 64] &= AL;
			ECX--;
		} while (!= 0);
		POPAD();
		return;
	}
	if (EAX == 2) { /* or */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			AL = [ES:EDI + 8]; /* color */
			EBX += [ES:EDI + 4];
			EDX += [ES:EDI + 0];
			IMUL(EBX, gbox->x_bsize);
			EDI += 12;
			EDX += EBX;
			(char) [DS:ESI + EDX + 64] |= AL;
			ECX--;
		} while (!= 0);
		POPAD();
		return;
	}
//	if (EAX == 3) { /* xor */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			AL = [ES:EDI + 8]; /* color */
			EBX += [ES:EDI + 4];
			EDX += [ES:EDI + 0];
			IMUL(EBX, gbox->x_bsize);
			EDI += 12;
			EDX += EBX;
			(char) [DS:ESI + EDX + 64] ^= AL;
			ECX--;
		} while (!= 0);
		POPAD();
		return;
//	}
}

void near cmd05c()
// points (graphicbox)
/* cmd, opt, graphicbox, x0, y0, xsize, ysize, points, ofs, sel */
/* optのbit15を1にすると、グラフィックボックスバッファにしか書き込まない */
{
	int *cmd == DS:ESI;
	WINDOW *win == SS:EBP;
	GRAPHBOX *gbox == DS:EDI;

	PUSH(ES);
	PUSH(EBP);
	PUSH((offset) cmd);
	EAX = cmd[ 4];
	EDX = cmd[12];
	EBX = cmd[16];
	ECX = cmd[28];
	asmout("LES EDI,DS:[ESI + 32]");
	ESI = cmd[ 8];
	cmd05c_sub();
	POP((offset) cmd);
	(offset) gbox = cmd[ 8];
	(offset) win = gbox->window;
	TEST(AH, 0x80);
	if (== 0) {
		if (win->draw_enable != 0) {
			PUSH((int) 0x0000);
			PUSH(ES);
			PUSH(cmd[32]);
			PUSH(ECX); /* points */
			PUSH(cmd[24]); /* ysize */
			PUSH(cmd[20]); /* xsize */
			EBX -= gbox->vy0;
			EDX -= gbox->vx0;
			EBX += gbox->y0;
			EDX += gbox->x0;
			PUSH(EBX);
			PUSH(EDX);
			PUSH(win->slot);
			PUSH(EAX); /* opt */
			PUSH((int) 0x041c); /* points */
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
			ESP += 44;
		}
	}
	(offset) cmd += 40;
	POP(EBP);
	POP(ES);
	asmout("JMP nextcmd");
}

void near cmd060()
// define signalbox
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EAX = work->signalbox_write_ptr;
	TEST(AL, 0x01);
	if (!= 0) {
		// シグナルフルだったので、それを解除
		PUSH((int) 0x0000); // eoc
		PUSH((int) 0xff02); // nest
		PUSH((int) 0); // signals
		PUSH((int) 0x0204); // add nest
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 16;
	}

	ECX = cmd[4]; // bytes /* bit0, 1はreserve */
	EAX = cmd[8]; // work_ptr
	ECX -= 4;
	LEA(EDX, [EAX + ECX]);
	ECX /= 4;
	work->signalbox_write_ptr = EAX;
	work->signalbox_write_ptr0 = EAX;
	work->signalbox_write_ptr1 = EDX;
	work->signalbox_write_free = ECX;
	work->signalbox_read_free = 0;
	ECX = cmd[12]; // eos
	EDX = cmd[16]; // rewind
	work->signalbox_eos = ECX;
	work->signalbox_rewind = EDX;
	(offset) cmd += 20;
	(int) [DS:EAX] = ECX; // eos
	asmout("JMP nextcmd");
}

void near cmd068()
// define signal
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EAX = cmd[4]; // opt
	TEST(AH, 0x30);
	if (!= 0) {
		// リザーブビット
		INT(0x03);
	}
	ECX = cmd[20]; // signal_length
	if ((unsigned) ECX >= 2) {
		// 1dwより長いシグナルには未対応
		INT(0x03);
	}
	if (ECX != 0) {
		// シェルに設定を送信：0x7f000001 signal
		EAX = cmd[8]; // device
		if (EAX == 0x0010 /* timer */) {
			PUSH((int) 0x0000);
			PUSH(cmd[24]); // signal
			PUSH((int) 0x7f000001);
			PUSH((int) 2 /* length */);
			PUSH((int) 0x0140);
			PUSH(cmd[12]); // timer slot-no
			PUSH((int) 0x0318);
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // shell-call
			ESP += 28;
		} else if (EAX == 0x0100) {
			WINDOW *cmd0068_win == DS:EDX;
			(offset) cmd0068_win = cmd[16]; // window
			if (EAX != 0x0100 /* decoded keycode */) {
				INT(0x03);
			}
			PUSH((int) 0);
			PUSH((int) 0);
			PUSH((int) 0); // for purpose
			PUSH(cmd[24]); // signal
			PUSH((int) 0x7f000001);
			PUSH((int) 2);
			PUSH((int) 0x0140 /* system signalbox(slot番号で指定) */);
			// ここにウィンドウ番号を入れた方がいいのでは？
			// もちろん、これもデフォルトの要請であって、受理されるとは限らない。
			PUSH(cmd0068_win->slot);
			PUSH(cmd[12]); // keycode
			PUSH(cmd[ 8]); // device
			PUSH(cmd[ 4]); // opt
			PUSH((int) 0x0510); // signal設定
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // shell-call
			ESP += 48;
		}
		(offset) cmd += 28;
		EAX = cmd[0];
		LEA((offset) cmd, [cmd + EAX * 4 + 4]);
		asmout("JMP nextcmd");
	} else {
		(offset) cmd += 24;
		EAX = cmd[0];
		LEA((offset) cmd, [cmd + EAX * 4 + 4]);
		asmout("JMP nextcmd");
	}
}

void near cmd070()
// タイマーノードオープン
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EDX = cmd[4];
	(offset) cmd += 8;
	if (EDX == 0x01c0) {
		// ユーザーモードに変更
		// 初期化する
cmd074_intervaloff:
		EAX = 0;
		PUSH(EAX);
		PUSH(EAX);
		PUSH(EAX);
		PUSH(EAX);
		PUSH(EDX);
		PUSH((int) 0x031c); // インターバル指定
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24;
		asmout("JMP nextcmd");
	}
	PUSH((int) 0x0000);
	PUSH(EDX);
	PUSH((int) 0x0300); // タイマーノード取得
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 12;
	asmout("JMP nextcmd");
asmout("cmd074_intervaloff EQU #cmd074_intervaloff");
}

void near cmd074()
// タイマーノードクローズ
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	EDX = cmd[4];
	(offset) cmd += 8;
	if (EDX == 0x01c0) {
		// システムモードに変更
		// 初期化する

		AX = CS;
		PUSH(FS);
		FS = AX;
		asmout("MOV EBX,OFFSET cmd004_cmd2");
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		POP(FS);
		asmout("JMP cmd074_intervaloff");
	}
	PUSH((int) 0x0000);
	PUSH(EDX);
	PUSH((int) 0x0304); // タイマーノード返却
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 12;
	asmout("JMP nextcmd");
}

void near cmd078()
// タイマー設定
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;

	// signalはここで設定しない
	// 時刻やインターバルを設定
	// シグナル定義時のdeviceは0x0010

	EAX = cmd[4]; // optionフィールド
	EDX = cmd[8]; // slot
	EBX = cmd[12]; /* slot1 */
	(offset) cmd += 12;

	ECX = 0;
	CMP(AL, 0x81);
	PUSH(ECX);
	if (==) {
		/* 時刻指定(含：時刻コピー) */
		PUSH(cmd[12]); /* cmd[24] */
		PUSH(cmd[ 8]); /* cmd[20] */
		PUSH(cmd[ 4]); /* cmd[16] */
		PUSH(EBX);
		PUSH(EDX);
		PUSH((int) 0x0320);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 28;
		(offset) cmd += 16;
		asmout("JMP nextcmd");
	}
	if (AL == 0x82) {
		/* 時間差分算出 */
		PUSH(ECX);
		PUSH(ECX);
		PUSH(ECX);
		PUSH(EBX);
		PUSH(EDX);
		PUSH((int) 0x0324); // 現在時刻設定
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 12;
		POP(cmd[ 4]); /* cmd[16] */
		POP(cmd[ 8]); /* cmd[20] */
		POP(cmd[12]); /* cmd[24] */
		(offset) cmd += 16;
		POP(ECX);
		asmout("JMP nextcmd");
	}
	TEST(AL, 0x20); // bit5 : 現在時刻ロード
	if (!= 0) {
	//	PUSH((int) 0x0000);
		PUSH(EDX);
		PUSH((int) 0x0310); // 現在時刻設定
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 12 - 4;
	}
	TEST(AL, 0x10); // bit4 : 時刻加算(時刻フィールドを伴う)
	if (!= 0) {
	//	PUSH((int) 0);
		PUSH(cmd[8]);
		PUSH(cmd[4]);
		PUSH(cmd[0]);
		(offset) cmd += 12;
		PUSH(EDX);
		PUSH((int) 0x0314); // 時刻加算
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24 - 4;
	}
	TEST(AL, 0x08); // bit3 : インターバル指定(インターバルフィールドを伴う)
	if (!= 0) {
	//	PUSH((int) 0);
		PUSH(cmd[8]);
		PUSH(cmd[4]);
		PUSH(cmd[0]);
		(offset) cmd += 12;
		PUSH(EDX);
		PUSH((int) 0x031c); // インターバル指定
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24 - 4;
	}
	TEST(AL, 0x04); // bit2 : インターバル解除(単発モード)
	if (!= 0) {
	//	PUSH(ECX);
		PUSH(ECX);
		PUSH(ECX);
		PUSH(ECX);
		PUSH(EDX);
		PUSH((int) 0x031c); // インターバル指定
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24 - 4;
	}
	TEST(AL, 0x02); // bit1 : タイマー始動
	if (!= 0) {
	//	PUSH((int) 0x0000);
		PUSH(EDX);
		PUSH((int) 0x0308); // タイマー登録
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 12 - 4;
	}
	TEST(AL, 0x01); // bit0 : タイマー停止
	if (!= 0) {
	//	PUSH((int) 0x0000);
		PUSH(EDX);
		PUSH((int) 0x030c); // タイマー解除
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 12 - 4;
	}
	POP(EAX);
	asmout("JMP nextcmd");
}

void near cmd080()
// サウンドトラックオープン
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[8] /* reserve */);
	PUSH(cmd[4] /* opt & slot */);
	PUSH((int) 0x0600);
	(offset) cmd += 12;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 16;

	// sleep
	LEA(EBX, work->softint_mask_buf[0]); // add_nest(Llv変更する)
//	work->softint_mask_buf[ 8] = 0x0080;
	(int) [DS:EBX + 8] = 0x0080;
	DB(0x9a); DD(0); DW(0x0017); // shell-call

	LEA(EBX, work->softint_mask_buf[0]); // add_nest(Llv変更しない)
//	work->softint_mask_buf[ 8] = 0xff80;
	(int) [DS:EBX + 8] = 0xff80;
		// ライブラリルーチン内に再入したので、割り込みマスク
	DB(0x9a); DD(0); DW(0x0017); // shell-call

	asmout("JMP nextcmd");
}

void near cmd084()
// サウンドトラッククローズ
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[4] /* opt & slot */);
	PUSH((int) 0x0604);
	(offset) cmd += 8;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 12;
	work->ending_count++;
	asmout("JMP nextcmd");
}

void near cmd08c()
// 周波数指定によるサウンドオン／オフ
{
	WORK *work == SS:EBP;
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[8]);
	PUSH(cmd[4] /* opt & slot */);
	PUSH((int) 0x060c);
	(offset) cmd += 12;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 16;
	asmout("JMP nextcmd");
}

void near cmd03c()
{
	WINDOW *win == DS:EDI;
	int *cmd == DS:ESI;

	EAX = cmd[4];
	(offset) win = cmd[8];
	TEST(AL, 0x01);
	if (!= 0) {
		// EBP, ESI, EDI以外は全て破壊
		drawwindow();
		EAX = cmd[4];
	}
	TEST(AL, 0x02);
	if (!= 0) {
		// EBP, ESI, EDI以外は全て破壊
		drawcomponent();
		EAX = cmd[4];
	}
	TEST(AH, 0x01);
	if (!= 0) {
		PUSH((int) 0);
		PUSH(win->slot);
		PUSH((int) 0x0140);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 12;
	}
	TEST(AH, 0x02);
	if (!= 0) {
		PUSH((int) 0);
		PUSH(win->slot);
		PUSH((int) 0x0144);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 12;
	}
	(offset) cmd += 12;
	asmout("JMP nextcmd");
}

void near cmd0a0()
/* ファイルハンドル初期化 */
{
	int *cmd == DS:ESI;
	EAX = cmd[ 4];
	PUSH((int) 0);
	if ((unsigned) EAX < 0xe0) {
		PUSH(cmd[ 8] /* slot */);
		PUSH(EAX /* opt */);
		PUSH((int) 0x0700);
		(offset) cmd += 12;
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 16;
		asmout("JMP nextcmd");
	}
	/* サブコマンド付き */
	/* cmd[12]はサブコマンド総バイト数 */
	PUSH(cmd[20] /* sel */);
	PUSH(cmd[16] /* ofs */);
	PUSH(cmd[12] /* bytes */);
	PUSH(cmd[ 8] /* slot */);
	PUSH((int) EAX);
	PUSH((int) 0x0700);
	(offset) cmd += 24;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 28;
	asmout("JMP nextcmd");
}

void near cmd0a8()
/* コピーハンドル */
/* cmd, opt, slot(dest), slot(src) */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[12] /* slot(src) */);
	PUSH(cmd[ 8] /* slot(dest) */);
	PUSH(cmd[ 4] /* opt */);
	PUSH((int) 0x0708);
	(offset) cmd += 16;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 20;
	asmout("JMP nextcmd");
}

void near cmd0ac()
/* ディレクトリ移動 */
/* cmd, opt, slot, bytes, ofs, sel */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[20] /* sel */);
	PUSH(cmd[16] /* ofs */);
	PUSH(cmd[12] /* bytes */);
	PUSH(cmd[ 8] /* slot */);
	PUSH(cmd[ 4] /* opt */);
	(offset) cmd += 24;
	PUSH((int) 0x070c);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 28;
	asmout("JMP nextcmd");
}

void near cmd0b0()
/* create new module */
/* cmd, opt, slot(dir), slot(module), tag-dir alloc-size, tag0, tag1, ..., -1 */
{
	int *cmd == DS:ESI;
	ESP -= 512;
	EAX = cmd[ 4];
	ECX = cmd[ 8];
	[SS:ESP + 508] = EBP;
	EBP = ESP;
	EDX = cmd[12];
	EBX = cmd[16];
	(offset) cmd += 20;
	(int) [SS:EBP +  0] = 0x0710;
	[SS:EBP +  4] = EAX;
	[SS:EBP +  8] = ECX;
	[SS:EBP + 12] = EDX;
	[SS:EBP + 16] = EBX;
	EBP += 20;
	EAX = cmd[0];
	do {
		ECX = cmd[4];
		(offset) cmd += 8;
		[SS:EBP    ] = EAX;
		[SS:EBP + 4] = ECX;
		EBP += 8;
		ECX -= 8;
		if (!= 0) {
			do {
				EAX = *cmd;
				(offset) cmd += 4;
				[SS:EBP] = EAX;
				EBP += 4;
				ECX -= 4;
			} while (!= 0);
		}
		EAX = cmd[0];
	} while (EAX != 0xffffffff);
	(offset) cmd += 4;
	(int) [SS:EBP    ] = EAX;
	(int) [SS:EBP + 4] = 0;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	EBP = [SS:ESP + 508];
	ESP += 512;
	asmout("JMP nextcmd");
}

void near cmd0c0()
/* モジュールのメモリマッピング */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[24] /* ofs & attr */);
	PUSH(cmd[20] /* sel */);
	PUSH(cmd[16] /* addr */);
	PUSH(cmd[12] /* size */);
	PUSH(cmd[ 8] /* slot */);
	PUSH(cmd[ 4] /* opt */);
	PUSH((int) 0x0720);
	(offset) cmd += 28;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 32;
	asmout("JMP nextcmd");
}

void near cmd0c4()
/* モジュールのアンマッピング */
{
	int *cmd == DS:ESI;
//	PUSH((int) 0);
//	PUSH(cmd[16] /* sel */);
//	PUSH(cmd[12] /* addr */);
//	PUSH(cmd[ 8] /* size */);
//	PUSH(cmd[ 4] /* opt */);
//	PUSH((int) 0x0720);
	(offset) cmd += 20;
//	EBX = ESP;
//	DB(0x9a); DD(0); DW(0x0017); // shell-call
//	ESP += 28;
	asmout("JMP nextcmd");
}

void near cmd0c8()
/* tag read */
/* cmd, opt, slot, bufsize, bufptr(near) */
/* opt == 0xffffff02 : module type code(8bytes) */
/* opt == 0xffffff03 : module size(16bytes) */
/* directoryに対してモジュールサイズを要求することはできない */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[20] /* bufptr(sel) */);
	PUSH(cmd[16] /* bufptr(ofs) */);
	PUSH(cmd[12] /* bufsize */);
	PUSH(cmd[ 8] /* slot */);
	PUSH(cmd[ 4] /* opt */);
	PUSH((int) 0x0728);
	(offset) cmd += 24;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 28;
	asmout("JMP nextcmd");
}

void near cmd0d0()
/* tag listing */
/* opt == 0xffffff00 : module name */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(DS /* bufptr(sel) */);
	PUSH(cmd[16] /* bufptr(ofs) */);
	PUSH(cmd[12] /* bufsize */);
	PUSH(cmd[ 8] /* slot */);
	PUSH(cmd[ 4] /* opt */);
	PUSH((int) 0x0730);
	(offset) cmd += 20;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 28;
	asmout("JMP nextcmd");
}

void near cmd0e0()
/* load font */
/* cmd, opt, slot, len, from(far) */
{
	int *cmd == DS:ESI;
	WORK *work == SS:EBP;
	EAX = cmd[ 4];
	PUSH((int) 0);
	if ((signed) EAX > 0) {
		PUSH(cmd[20]);
		PUSH(cmd[16]);
		PUSH(cmd[12]);
		PUSH(cmd[ 8]);
		PUSH(EAX);
		PUSH((int) 0x0408);
		(offset) cmd += 24;
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 28;
		asmout("JMP nextcmd");
	}
	if ((unsigned) EAX >= 0xc0000001) {
		/* カスタムモード(完了シグナル付き) */
		PUSH(cmd[16]); /* sig(0x7f000001は付かない) */
		PUSH(cmd[12]); /* len */
		PUSH(cmd[ 8]);
		PUSH(EAX);
		PUSH((int) 0x0408);
		(offset) cmd += 20;
		EBX = ESP;
		if (EAX == 0xc0ffffff)
			work->ending_count++;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 24;
		asmout("JMP nextcmd");
	}
	if ((unsigned) EAX >= 0x80000001) {
		/* カスタムモード(完了シグナルなし) */
		PUSH(cmd[ 8]);
		PUSH(EAX);
		PUSH((int) 0x0408);
		(offset) cmd += 12;
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // shell-call
		ESP += 16;
		asmout("JMP nextcmd");
	}
	INT(0x03);
}

void near cmd0e4()
/* free font */
/* cmd, opt, slot */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[ 8]);
	PUSH(cmd[ 4]);
	PUSH((int) 0x040c);
	(offset) cmd += 12;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 16;
	asmout("JMP nextcmd");
}

void near cmd0e8()
/* make charset */
/* cmd, opt, slot(charset), slot(font), range, from, to */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[24]);
	PUSH(cmd[20]);
	PUSH(cmd[16]);
	PUSH(cmd[12]);
	PUSH(cmd[ 8]);
	PUSH(cmd[ 4]);
	PUSH((int) 0x0410);
	(offset) cmd += 28;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 32;
	asmout("JMP nextcmd");
}

void near cmd0ec()
/* code convert */
/* cmd, opt, len, src, dest, base0, base1,... */
/* opt 0x0001 : SJIS to GUIGUI00-JPN(1) */
/* opt 0x0002 : シンプルEUC */
/*   written by I.Tak. [OSASK 2945] */
{
	unsigned int EOSp == EBX, G0base == ECX, G1base == EBP;
	unsigned char *src == DS:ESI;
	unsigned int *dst == ES:EDI, *cmd == SS:EBP;

	PUSH(ES);
	PUSH(DS);
	PUSH(EBP);
	(offset) cmd = ESI;
	EOSp = cmd[ 8];					/* length of generated GUIGUI-code */
	EAX  = cmd[ 4];					/* opt */
	asmout("LES EDI,SS:[EBP+20]");	/* dst */
	asmout("LDS ESI,SS:[EBP+12]");	/* src */
//	LEA(EOSp, (int) dst[EOSp * 4]);	/* points end of dst string */
	LEA(EBX, [EDI + EBX * 4]);

	if (AL == 0x03)
		goto mode0003;				/* Fundamental EUC */

	PUSH((offset) cmd);
	G0base = cmd[28];
	G1base = cmd[32];
	EAX--;
	if (== 0)
		goto mode0001;				/* 日本語WindowsのシフトJIS */
	EAX--;
	if (== 0)
		goto mode0002;				/* とっても簡単にしちゃったEUC */
	INT(0x03);

mode0001:
/******* Shifted-JIS with MS extension conveter V0.2 */
	do {
		EAX = *src;
		(offset) src++;
		EDX = EAX;
		AL ^= 0xa0;
		AL -= 0x21;
		if ((unsigned) AL < 47) {
			/* 0x81-0x9f, 0xe0-0xef: X0213-1 */
			DL = *src;					/* second byte */
			(offset) src++;
			DL -= 0x80;
			ADC(DL, 63);				/* AL -= (AL < 0x80) ? 64:65 */
DoubleWidth2:
			IMUL(EAX, 94 * 2 * 2);
			LEA(EDX, [EAX + EDX * 2]);
			EDX += G1base;
			dst[0] = EDX;
			EDX++;
			dst[4] = EDX;
			(offset) dst += 8;
		} else {
			AL -= 47 + 10;
			if((unsigned) AL < 3) {
				/* 0xfa-0xfc:MS&NEC extension */
				AL += 94 / 2;
				DL = *src;
				(offset) src++;
			//	EDX += 0 - 0x80;			/* shorter */
				EDX -= 0x80;				/* bug fixed. */
				ADC(EDX, 63 - 28);
				asmout("JNS #DoubleWidth2");	/* if( SF==0 ) */
				if (AL != 94 / 2)			/* 95区か96区 */
					goto DoubleWidth2;
				AL = 100 / 2;				/* MS28文字を101区へ */
				EDX += 28;
				goto DoubleWidth2;
			}
			/* X0201 */
			EDX += G0base;
			*dst = EDX;
			(offset) dst += 4;
		}
	} while ((unsigned) (offset) dst < EOSp);

endconv:
	POP(ESI);
	POP(EBP);
	POP(DS);
	POP(ES);
	ESI += 36;	/* points next command */
	asmout("JMP nextcmd");

mode0002:
/****** Easy EUC convertor V0.1.1 */
	do {
		EAX = *src;
		(offset) src++;
		EDX = EAX;
		AL -= 0xa1;
		if ((unsigned) >= 0) {
			/* GR or 0xff */
			IMUL(EDX, EAX, 94 * 2);
			AL = *src;
			(offset) src++;
			AL -= 0x21;
			AL &= 0x7f;			/* easy triming */
			LEA(EDX, [EAX * 2 + EDX]);
			EDX += G1base;
			dst[0] = EDX;
			EDX++;
			dst[4] = EDX;
			(offset) dst += 8;
		} else {
			/* C0,0x20,GL,0x7f,C1,0x80 */
			EDX += G0base;
			*dst = EDX;
			(offset) dst += 4;
		}
	} while ((unsigned) (offset) dst < EOSp);
	goto endconv;

mode0003:
/******* Fundamental EUC converter V0.1.1 */
	do {
		/* First Phase */
		AL = *src;
		(offset) src++;
		ECX = 0;				/* 中間バッファ番号 */
		TEST(AL, AL);
		DL = 3;					/* mask */
		if ((signed) < 0) {		/* C1 or GR */
			ECX++;
			if ((unsigned) AL <= 0x8f) {	/* SS2 手抜き */
				SBB(CL, 0 - 2);	/* cl+=(CF)?1:2 */
				AL = *src;
				(offset) src++;
			}
			ECX *= 2;
		}
		EAX &= 0x7f;

		/* Second Phase */
		(unsigned char) DL <<= CL;	/* mask */
		ECX = cmd[ECX * 2 + 28];	/* base */
		DL &= (char) cmd[4 + 2];
		if (== 0) {				/* 1byte set */
			EAX += ECX;
			*dst = EAX;
			(offset) dst += 4;
		} else {				/* 94^2 set */
			AL -= 0x21;
			CMP(AL, 94);		/* triming */
			SBB(DL, DL);		/* triming */
			AL &= DL;			/* triming */
			IMUL(EDX, EAX, 94 * 2);
			AL = *src;			/* second byte */
			EDX += ECX;			/* base */
			AL -= 0x21;
			(offset) src++;
			EAX &= 0x7f;		/* easy triming */
			LEA(EDX, [EDX + EAX * 2]);
			dst[0] = EDX;
			EDX++;
			dst[4] = EDX;
			(offset) dst += 8;
		}
	} while ((unsigned) (offset) dst < EOSp);

	ESI = (offset)cmd;
	POP(EBP);
	POP(DS);
	POP(ES);
	ESI += 44;
	asmout("JMP nextcmd");
}

void near cmd0f0()
/* set segment */
/* cmd, opt, selector, ar, limit, offset, base_selector */
/* selectorとbase_selectorは0xfff8でマスクしておくこと */
{
	int *cmd == DS:ESI;
	PUSH((int) 0);
	PUSH(cmd[24]);
	PUSH(cmd[20]);
	PUSH(cmd[16]);
	PUSH(cmd[12]);
	PUSH(cmd[ 8]);
	PUSH(cmd[ 4]);
	PUSH((int) 0x0240);
	(offset) cmd += 28;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	ESP += 32;
	asmout("JMP nextcmd");
}

void near cmd108_sub_pset()
/*
	ESI : 初期x
	EDI : 初期y
	EDX : 増分値x
	EBX : 増分値y
	EBP : ループ回数
	EAX : カラー
	ECX : gbox
*/
{
	GRAPHBOX *gbox == DS:ECX;

	PUSH(ECX);
	PUSH(gbox->x_bsize);
	PUSH(EBP);
	PUSH(EAX);
	LEA(EBP, [ECX + 64]);
	ECX = EDI;
	EAX = ESI;
	(unsigned int) ECX >>= 16;
	(unsigned int) EAX >>= 16;
	IMUL(ECX, (int) [SS:ESP + 8]);
	EBP += EAX;
	EAX = 0x00010000;
	EBP += ECX;
	ECX = 0xffff0000;
	if (EBX == EAX) {
		if (EDX == EAX)
			goto line_xp1_yp1;
		if ((signed) > )
			goto general;
		if (EDX >= 0)
			goto line_xpd_yp1;
		if (EDX == ECX)
			goto line_xm1_yp1;
		if ((signed) < )
			goto line_xmd_yp1;
	} else if (EBX == ECX) {
		if (EDX == EAX)
			goto line_xp1_ym1;
		if ((signed) > )
			goto general;
		if (EDX >= 0)
			goto line_xpd_ym1;
		if (EDX == ECX)
			goto line_xm1_ym1;
		if ((signed) < )
			goto line_xmd_ym1;
	} else if (EDX == EAX) {
	//	if (EBX == EAX)
	//		goto line_xp1_yp1;
		if ((signed) EBX > EAX)
			goto general;
		if (EBX >= 0)
			goto line_xp1_ypd;
	//	if (EBX == ECX)
	//		goto line_xp1_ym1;
		if ((signed) EBX < ECX)
			goto line_xp1_ymd;
	} else if (EDX == ECX) {
	//	if (EBX == EAX)
	//		goto line_xm1_yp1;
		if ((signed) EBX > EAX)
			goto general;
		if (EBX >= 0)
			goto line_xm1_ypd;
	//	if (EBX == ECX)
	//		goto line_xm1_ym1;
		if ((signed) EBX < ECX)
			goto line_xm1_ymd;
	}

general:
	POP(EAX);
	POP(EBP);
	PUSH(EDX);
	do {
		EDX = EDI;
		ECX = ESI;
		(unsigned int) EDX >>= 16;
		(unsigned int) ECX >>= 16;
		IMUL(EDX, (int) [SS:ESP + 4]);
		ECX += (int) [SS:ESP + 8];
		ESI += [SS:ESP];
		EDI += EBX;
		(char) [DS:EDX + ECX + 64] = AL;
		EBP--;
	} while (!= 0);
	POP(EDX);
	POP(EAX);
	POP(ECX);
	return;

line_xpd_yp1:
	EDI = EBP;
	EBP = [SS:ESP + 8];
line_xpmd_yp1:
	POP(EAX);
	ESI <<= 16;
	POP(ECX);
	EDX <<= 16;
	do {
		(char) [DS:EDI] = AL;
		ESI += EDX;
		ADC(EDI, EBP);
		ECX--;
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xmd_yp1:
	EDI = EBP;
	EBP = [SS:ESP + 8];
	EBP--;
	goto line_xpmd_yp1;

line_xpd_ym1:
	EDI = EBP;
	EBP = [SS:ESP + 8];
	EBP =- EBP;
	goto line_xpmd_yp1;

line_xmd_ym1:
	EDI = EBP;
	EBP = [SS:ESP + 8];
	EBP =- EBP;
	EBP--;
	goto line_xpmd_yp1;

line_xp1_ypd:
	ESI = EBP;
	POP(EAX);
	EDI <<= 16;
	POP(ECX);
	EBX <<= 16;
	do {
		EDI += EBX;
		SBB(EDX, EDX); /* CF == 0ならEDX = 0, CF == 1ならEDX = -1 */
		(char) [DS:ESI] = AL;
		EDX &= [SS:ESP + 0];
		ECX--;
		LEA(ESI, [ESI + EDX + 1]);
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xp1_ymd:
	ESI = EBP;
	POP(EAX);
	EDI <<= 16;
	POP(ECX);
	EBX <<= 16;
	NEG((int) [SS:ESP + 0]);
	do {
		EDX = 0;
		EDI += EBX;
		ADC(EDX, 0xffffffff); /* CF == 0ならEDX = -1, CF == 1ならEDX = 0 */
		(char) [DS:ESI] = AL;
		EDX &= [SS:ESP + 0];
		ECX--;
		LEA(ESI, [ESI + EDX + 1]);
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xm1_ypd:
	ESI = EBP;
	POP(EAX);
	EDI <<= 16;
	POP(ECX);
	EBX <<= 16;
	do {
		EDI += EBX;
		SBB(EDX, EDX); /* CF == 0ならEDX = 0, CF == 1ならEDX = -1 */
		(char) [DS:ESI] = AL;
		EDX &= [SS:ESP + 0];
		ECX--;
		LEA(ESI, [ESI + EDX - 1]);
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xm1_ymd:
	ESI = EBP;
	POP(EAX);
	EDI <<= 16;
	POP(ECX);
	EBX <<= 16;
	NEG((int) [SS:ESP + 0]);
	do {
		EDX = 0;
		EDI += EBX;
		ADC(EDX, 0xffffffff); /* CF == 0ならEDX = -1, CF == 1ならEDX = 0 */
		(char) [DS:ESI] = AL;
		EDX &= [SS:ESP + 0];
		ECX--;
		LEA(ESI, [ESI + EDX - 1]);
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xp1_yp1:
	EDX = [SS:ESP + 8];
	EDX++;
line_x1_y1:
	POP(EAX);
	ESI = EBP;
	POP(ECX);
	do {
		(char) [DS:ESI] = AL;
		ESI += EDX;
		ECX--;
	} while (!= 0);
	POP(EAX);
	POP(ECX);
	return;

line_xp1_ym1:
	EDX = 1;
	EDX -= [SS:ESP + 8];
	goto line_x1_y1;

line_xm1_yp1:
	EDX = [SS:ESP + 8];
	EDX--;
	goto line_x1_y1;

line_xm1_ym1:
	EDX = 0xffffffff;
	EDX -= [SS:ESP + 8];
	goto line_x1_y1;
}

void near cmd108_sub()
/* EAX == opt, lines == ECX, dat == ES:EDI, gbox == DS:ESI */
/* EDX == x0, EBX == y0 */
{
	GRAPHBOX *gbox == DS:ESI;

	EDX <<= 16;
	EBX <<= 16;
	PUSHAD();
	EAX >>= 6;
	EAX &= 0x03;
	if (== 0) { /* pset */
		do {
			PUSH(ESI);
			EDX = [ES:EDI +  8];
			PUSH(ECX);
			EBX = [ES:EDI + 12];
			EBP = [ES:EDI + 16];
			EAX = [ES:EDI + 20];
			PUSH(EDI);
			ECX = (offset) gbox;
			ESI = [ES:EDI +  0];
			EDI = [ES:EDI +  4];
			ESI += [SS:ESP + 32]; /* x0 */
			EDI += [SS:ESP + 28]; /* y0 */
			cmd108_sub_pset();
			POP(EDI);
			POP(ECX);
			EDI += 24;
			POP(ESI);
			ECX--;
		} while (!= 0);
		POPAD();
		(unsigned int) EDX >>= 16;
		(unsigned int) EBX >>= 16;
		return;
	}
	if (EAX == 1) { /* and */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			PUSH(ECX);
			AL = [ES:EDI + 20]; /* color */
			PUSH(EDI);
			EBX += [ES:EDI +  4];
			PUSH((int) [ES:EDI + 12]);
			EDX += [ES:EDI +  0];
			PUSH((int) [ES:EDI +  8]);
			EBP = [ES:EDI + 16];
			do {
				ECX = EBX;
				EDI = EDX;
				(unsigned int) ECX >>= 16;
				(unsigned int) EDI >>= 16;
				IMUL(ECX, gbox->x_bsize);
				EDX += [SS:ESP + 0];
				EDI += ECX;
				EBX += [SS:ESP + 4];
				(char) [DS:ESI + EDI + 64] &= AL;
				EBP--;
			} while (!= 0);
			POP(EAX);
			POP(EDX);
			POP(EDI);
			POP(ECX);
			EDI += 24;
			ECX--;
		} while (!= 0);
		POPAD();
		(unsigned int) EDX >>= 16;
		(unsigned int) EBX >>= 16;
		return;
	}
	if (EAX == 2) { /* or */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			PUSH(ECX);
			AL = [ES:EDI + 20]; /* color */
			PUSH(EDI);
			EBX += [ES:EDI +  4];
			PUSH((int) [ES:EDI + 12]);
			EDX += [ES:EDI +  0];
			PUSH((int) [ES:EDI +  8]);
			EBP = [ES:EDI + 16];
			do {
				ECX = EBX;
				EDI = EDX;
				(unsigned int) ECX >>= 16;
				(unsigned int) EDI >>= 16;
				IMUL(ECX, gbox->x_bsize);
				EDX += [SS:ESP + 0];
				EDI += ECX;
				EBX += [SS:ESP + 4];
				(char) [DS:ESI + EDI + 64] |= AL;
				EBP--;
			} while (!= 0);
			POP(EAX);
			POP(EDX);
			POP(EDI);
			POP(ECX);
			EDI += 24;
			ECX--;
		} while (!= 0);
		POPAD();
		(unsigned int) EDX >>= 16;
		(unsigned int) EBX >>= 16;
		return;
	}
//	if (EAX == 3) { /* xor */
		do {
			EBX = [SS:ESP + 16]; /* y0 */
			EDX = [SS:ESP + 20]; /* x0 */
			PUSH(ECX);
			AL = [ES:EDI + 20]; /* color */
			PUSH(EDI);
			EBX += [ES:EDI +  4];
			PUSH((int) [ES:EDI + 12]);
			EDX += [ES:EDI +  0];
			PUSH((int) [ES:EDI +  8]);
			EBP = [ES:EDI + 16];
			do {
				ECX = EBX;
				EDI = EDX;
				(unsigned int) ECX >>= 16;
				(unsigned int) EDI >>= 16;
				IMUL(ECX, gbox->x_bsize);
				EDX += [SS:ESP + 0];
				EDI += ECX;
				EBX += [SS:ESP + 4];
				(char) [DS:ESI + EDI + 64] ^= AL;
				EBP--;
			} while (!= 0);
			POP(EAX);
			POP(EDX);
			POP(EDI);
			POP(ECX);
			EDI += 24;
			ECX--;
		} while (!= 0);
		POPAD();
		(unsigned int) EDX >>= 16;
		(unsigned int) EBX >>= 16;
		return;
//	}
}

void near cmd108()
// lines (graphicbox)
/* cmd, opt, graphicbox, x0, y0, xsize, ysize, lines, ofs, sel */
/* 変換処理はcmd10cで行う */
/* optのbit15を1にすると、グラフィックボックスバッファにしか書き込まない */
{
	int *cmd == DS:ESI;
	WINDOW *win == SS:EBP;
	GRAPHBOX *gbox == DS:EDI;

	PUSH(ES);
	PUSH(EBP);
	PUSH((offset) cmd);
	EAX = cmd[ 4];
	EDX = cmd[12];
	EBX = cmd[16];
	ECX = cmd[28];
	asmout("LES EDI,DS:[ESI + 32]");
	ESI = cmd[ 8];
	cmd108_sub();
	POP((offset) cmd);
	(offset) gbox = cmd[ 8];
	(offset) win = gbox->window;
	TEST(AH, 0x80);
	if (== 0) {
		if (win->draw_enable != 0) {
			PUSH((int) 0x0000);
			PUSH(ES);
			PUSH(cmd[32]);
			PUSH(ECX); /* lines */
			PUSH(cmd[24]); /* ysize */
			PUSH(cmd[20]); /* xsize */
			EBX -= gbox->vy0;
			EDX -= gbox->vx0;
			EBX += gbox->y0;
			EDX += gbox->x0;
			PUSH(EBX);
			PUSH(EDX);
			PUSH(win->slot);
			PUSH(EAX); /* opt */
			PUSH((int) 0x0418); /* linear dots */
			EBX = ESP;
			DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
			ESP += 44;
		}
	}
	(offset) cmd += 40;
	POP(EBP);
	POP(ES);
	asmout("JMP nextcmd");
}

void near cmd10c()
// lines convert
/* cmd, opt, lines, src_ofs, src_sel, dest_ofs, dest_sel */
	/* x0, y0, x1, y1, dummy, color (line-compatible) */
	/* x0, y0, dx, dy, dots, color */
{
	int *cmd == DS:ESI;
	PUSH(ES);
	PUSH(DS);
	PUSH(ESI);
	PUSH(EBP);
	ECX = cmd[ 8]; /* lines */
	asmout("LES EDI,DS:[ESI + 20]");
	asmout("LDS ESI,DS:[ESI + 12]");
	do {
		PUSH(ECX);
		EDX = [DS:ESI +  0];
		EBX = [DS:ESI +  4];
		EAX = [DS:ESI +  8];
		ECX = [DS:ESI + 12];
		lineconv();
		EBP++;
		[ES:EDI +  0] = EDX;
		[ES:EDI +  4] = EBX;
		EDX = [DS:ESI + 20];
		ESI += 24;
		[ES:EDI +  8] = EAX;
		[ES:EDI + 12] = ECX;
		POP(ECX);
		[ES:EDI + 16] = EBP;
		[ES:EDI + 20] = EDX;
		EDI += 24;
		ECX--;
	} while (!= 0);
	POP(EBP);
	POP(ESI);
	POP(DS);
	(offset) cmd += 28;
	POP(ES);
	asmout("JMP nextcmd");
}



#if 0

void near cmd110()
// lines (window)
/* cmd, opt, window, x0, y0, xsize, ysize, lines, ofs, sel */
/* 変換処理はcmd10cで行う */
/* optのbit15を1にすると、ウィンドウライトディゼーブルのときは書き込まない */
{
	int *cmd == DS:ESI;
	WINDOW *win == DS:ECX;

	EAX = cmd[ 4];
	PUSH(EBP);
	(offset) win = cmd[ 8];
	EDX = 0;
	EBP = cmd[12];
	EDI = cmd[16];
	if ((unsigned) (offset) win == 0xffffffff) /* 常にイネーブルとみなす */
		goto draw;
	EBP += win->x_ofs;
	EDI += win->y_ofs;
	CMP(win->draw_enable, 0);
	EDX = win->slot;
	if (!= 0)
		goto draw;
	TEST(AH, 0x80);
	if (== 0) {
draw:
		AH &= 0x7f;
		PUSH((int) 0x0000);
		PUSH(cmd[36]);
		PUSH(cmd[32]);
		PUSH(cmd[28]); /* lines */
		PUSH(cmd[24]); /* ysize */
		PUSH(cmd[20]); /* xsize */
		PUSH(EDI);
		PUSH(EBP);
		PUSH(EDX);
		PUSH(EAX); /* opt */
		PUSH((int) 0x0418); /* linear dots */
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 44;
	}
	(offset) cmd += 40;
	POP(EBP);
	asmout("JMP nextcmd");
}
#endif

void near cmd118()
/* get randseed */
/* cmd, opt, (seed) */
{
	int *cmd == DS:ESI;

	PUSH((int) 0x0000);
	PUSH(EAX);
	PUSH((int) 0x0328);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	POP(EAX);
	POP(cmd[8]);
	POP(EAX);
	(offset) cmd += 12;
	asmout("JMP nextcmd");
}

void near cmd120()
/* file resize */
/* cmd, opt(0:absolute), slot, new-size, siglen, sig */
{
	int *cmd == DS:ESI;

	PUSH((int) 0x0000);
	PUSH(cmd[20]); /* sig */
	PUSH(cmd[16]); /* siglen */
	PUSH(cmd[12]); /* new-size */
	PUSH(cmd[ 8]); /* slot */
	PUSH(cmd[ 4]); /* opt */
	PUSH((int) 0x0740);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 28;
	(offset) cmd += 24;
	asmout("JMP nextcmd");
}

void near sendusersignal()
// ES:EDIからのECX[dw]を送信
// ESI, EBP以外のレジスタは破壊される
// 送信に失敗したら、フラグで伝達(ZF == 0はエラー)
{
	WORK *work == SS:EBP;
	EDX = work->signalbox_write_ptr;
	TEST(DL, 0x03);
	if (== 0) {
		LEA(EAX, [EDX + ECX * 4]);
		if ((unsigned) EAX >= work->signalbox_write_ptr1 /* 書き込み上限アドレス */) {
			/* 先頭に戻す */
			/* 捨てるdw数を計算 */
			EAX = work->signalbox_write_ptr1;
			EAX -= EDX;
			EAX /= 4; // EAX == 先頭に戻すことによって消費するサイズ(dw単位)
			work->signalbox_read_free += EAX;
			work->signalbox_write_free -= EAX;
			if ((unsigned) <= 0) {
				work->signalbox_read_free -= EAX;
				work->signalbox_write_free += EAX;
				TEST(ESP, ESP); // ZF = 0
				return;
			} else {
				EBX = work->signalbox_rewind;
				[DS:EDX + 4] = EAX;
				[DS:EDX] = EBX;
				EDX = work->signalbox_write_ptr0;
			}
		}
		work->signalbox_read_free += ECX;
		work->signalbox_write_free -= ECX;
		if ((unsigned) <= 0) {
			// ユーザー用のsignalboxがあふれた
			work->signalbox_read_free -= ECX;
			work->signalbox_write_free += ECX;
			TEST(ESP, ESP); // ZF = 0
			EAX = work->signalbox_eos;
			work->signalbox_write_ptr = EDX;
			(int) [DS:EDX] = EAX;
			return;
		}
		do {
			EAX = [ES:EDI];
			EDI += 4;
			(int) [DS:EDX] = EAX;
			EDX += 4;
			ECX--;
		} while (!= 0); // ZF == 1
		EAX = work->signalbox_eos;
		work->signalbox_write_ptr = EDX;
		(int) [DS:EDX] = EAX;
		// nestによらず、目を覚まさせる
	//	(char) [SS:ESP + 12 /* GS, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	}
	return;
}

// ユーザーシグナルボックスがないうちに、ユーザーシグナルが来たら、シグナルをマスク

void far pioneer_softint()
{
	WORK *work == SS:EBP;
	int *signal == GS:ESI;

	PUSH(DS);
	PUSH(ES);
	PUSH(GS);
	AX = SS;
	ECX = 0x0027; // system signalbox selector
	DS = AX;
	FS = AX;
	GS = CX;

	EBX = 0xffffffff;
	EAX = 0x0004; // リードユーザースロットコマンド
	ECX = 0x01f0;
	DB(0x9a); DD(0); DW(0x0017); // shell-call
	(offset) work = EDX;

	(offset) signal = work->read_ptr;
	work->signaldw = 0;
	do {
		EAX = signal[0];
		if (EAX == 0) {
			// terminate
			break;
		}
		if ((signed) <)
			goto usersignal;
		if ((unsigned) EAX >  0x7f0000ff)
			goto undefined;
		if ((unsigned) EAX >= 0x7f000000)
			goto headercut;
		if (EAX == 0x0080)
			goto sig0080; // system-timer time out
		if (EAX == 1)
			goto sig0001; // rewind
		if (EAX == 0x40)
			goto sig0040; // set window position
		if (EAX == 0x41)
			goto sig0041; // change window title-bar color
		if (EAX == 0x42)
			goto sig0042; // VRAM access enable(window)
		if (EAX == 0x43)
			goto sig0043; // close window
		if (EAX == 0x44)
			goto sig0044; // VRAM access disable(window)
		if (EAX == 0x45)
			goto sig0045; // closed window
		if (EAX == 0x48)
			goto sig0048; // redraw window
		if (EAX == 0xc0)
			goto sig00c0; // open sound track
		if (EAX == 0xc4)
			goto sig00c4; // closed sound track
		if (EAX == 0xc8)
			goto sig00c8; // enable sound track
		if (EAX == 0xcc)
			goto sig00cc; /* loaded font (2dw) */
		INT(0x03);

usersignal:
	// ユーザーシグナル：未対応
	INT(0x03);

undefined:
	// 未定義のシグナル
	INT(0x03);

headercut:
	// ユーザーシグナル(ヘッダーカット)
	EAX &= 0xff;
	EDX = 0x0027; // system signalbox selector
	ECX = EAX;
	EAX++;
	ES = EDX;
	PUSH(EAX);
//	EDI = (offset) signal + 4;
	LEA(EDI, [ESI + 4]);
	sendusersignal();
	POP(EAX);
	if (ZF == 1 /* succeeded */) {
		work->signaldw += EAX;
		LEA(ESI, [ESI + EAX * 4]);
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
		goto nextsignal;
	}
//	goto usersigboxfull;

usersigboxfull:
	// nestを0x02だけ減らす。
	work->signalbox_status |= 0x01 /* buffer-full */;
	work->signalbox_write_ptr |= 0x01 /* buffer-full */;
	EAX = work->signaldw; // それまでに処理できたシグナル
	POP(GS);
	POP(ES);
	POP(DS);
	LEA(EBX, work->softint_ret_buf[0]);
	work->softint_ret_buf[ 4] /* (int) [DS:EBX + 4] */ = EAX;
	work->softint_ret_buf[ 8] /* (int) [DS:EBX + 8] */ = 0x00ff; // さらに1引く
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	// 割り込みから復帰してしまう

sig0080:
	// システムタイマータイムアウト
	(offset) signal += 4;
	work->signaldw++;
	(char) [SS:ESP + 12 /* GS, ES, DS */ + 16 /* ESP */] = 0x02; // リターン時にLlv2へ。
	goto nextsignal;

sig00c0:
	// open sound track
	EDX = signal[4]; // slot
	EAX = signal[8]; // system-id
	(offset) signal += 12;
	work->signaldw += 3;
	(char) [SS:ESP + 12 /* GS, ES, DS */ + 16 /* ESP */] = 0x02; // リターン時にLlv2へ。
	EDX |= 0x01; // system-id defined
	PUSH((int) 0);
	PUSH(EAX);
	PUSH(EDX);
	PUSH((int) 0x0600);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 16;
	goto nextsignal;

sig00c8:
	// enable sound track
	EDX = signal[4]; // slot
	(offset) signal += 8;
	work->signaldw += 2;
	EDX |= 0x01; // enable
	PUSH((int) 0);
	PUSH(EDX);
	PUSH((int) 0x0608);
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 12;
	goto nextsignal;

sig0001:
	// rewind
	EAX = signal[4];
	(offset) signal = 0;
	work->signaldw += EAX;
	goto nextsignal;

sig0040:
	// window位置変更
	// 描画は全てwindow相対モードを使うので、このシグナルに応じる必要が無い
	WINDOW *sig0040_win == DS:EBX;
	(offset) sig0040_win = signal[4];
//	EAX = signal[ 8];
//	ECX = signal[12];
//	*win_x0 = EAX; // win_x0
//	*win_y0 = ECX; // win_y0
	AL = sig0040_win->sigflag;
	TEST(AL, 0x02);
	if (!= 0) {
		EDI = 4;
		TEST(AL, 0x80);
		EDX = sig0040_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		PUSH(signal[12]);
		PUSH(signal[ 8]);
		PUSH(EDX);
		ECX = 3;
		EDI = ESP;
		sendusersignal();
		LEA(ESP, [SS:ESP + 12]);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	}
	(offset) signal += 16;
	work->signaldw += 4;
	goto nextsignal;

sig0041:
	// タイトルバーカラー変更
	// bit0 : 0 = 長期にわたり、自由表示disable, 1 = enable
	// bit1 : 0 = 入力アクティブではない, 1 = 入力アクティブ
	// ぐいぐいでは、10の組み合わせをしないことを保証している。重なっていると入力アクティブにならない。
	// 入力アクティブになると、カーソルを表示する。

	WINDOW *sig0041_win == DS:EBX;
	(offset) sig0041_win = signal[4];
	AL = (char) signal[8];
	sig0041_win->mode0 = AL;
	AL = sig0041_win->sigflag;
	TEST(AL, 0x04);
	if (!= 0) {
		EDI = 5;
		TEST(AL, 0x80);
		EDX = sig0041_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		PUSH(signal[8]);
		PUSH(EDX);
		ECX = 2;
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		POP(EDI);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	}
	(offset) signal += 12;
	work->signaldw += 3;
	goto nextsignal;

sig0042:
	// VRAMアクセスの自由化
	WINDOW *sig0042_win == DS:EBX;
	(offset) sig0042_win = signal[4];
	AL = sig0042_win->sigflag;
	sig0042_win->draw_enable = 1; // 自由表示enable（随時更新）
	TEST(AL, 0x10);
	if (!= 0) {
		PUSH(sig0042_win->signalhead[0]);
		PUSH(SS);
		ECX = 1;
		POP(ES);
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	}
	(offset) signal += 8;
	work->signaldw += 2;
	goto nextsignal;

sig0043:
	// ウィンドウクローズ要求
	WINDOW *sig0043_win == DS:EBX;
	(offset) sig0043_win = signal[4];
	AL = sig0043_win->sigflag;
	TEST(AL, 0x08);
	if (!= 0) {
		EDI = 6;
		TEST(AL, 0x80);
		EDX = sig0043_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		PUSH(EDX);
		ECX = 1;
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
		(offset) signal += 8;
		work->signaldw += 2;
		goto nextsignal;
	}

	PUSH((int) 0);
	PUSH((int) 0x0001); // opt(close all handle)
	PUSH((int) 0x0040); /* タスク終了 */
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
	AL = [SS:ESP + 6];
	ESP += 12;
	AL += work->ending_count;
	(offset) signal += 8;
	work->signaldw += 2;
	AL &= 0x7f;	
	work->ending_count = AL;
	if (!= 0)
		goto nextsignal;
	PUSH((int) 0);
	PUSH((int) 0x0002); // opt(close task)
	PUSH((int) 0x0040); /* タスク終了 */
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
	INT(0x03);

sig0044:
	// VRAMアクセスの凍結
	WINDOW *sig0044_win == DS:EBX;
	(offset) sig0044_win = signal[4];
	AL = sig0044_win->sigflag;
	TEST(AL, 0x10);
	sig0044_win->draw_enable = 0; // 自由表示disable（更新抑制）
	if (!= 0) {
		EDI = 1;
		TEST(AL, 0x80);
		EDX = sig0044_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		PUSH(EDX);
		ECX = 1;
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	} else {
		// 受理したことをシェルにシステムコールで伝える
		PUSH((int) 0);
		PUSH(sig0044_win->slot);
		PUSH((int) 0x0140);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 12;
	}
	(offset) signal += 8;
	work->signaldw += 2;
	goto nextsignal;

sig0045:
	/* ウィンドウクローズ完了報告 */
	WINDOW *sig0045_win == DS:EBX;
	(offset) sig0045_win = signal[4];
	AL = sig0045_win->sigflag;
	TEST(AL, 0x20);
	if (!= 0) {
		EDI = 7;
		TEST(AL, 0x80);
		EDX = sig0045_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		ECX = 1;
		PUSH(EDX);
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	}
sig00c4:
sig00cc:
	(offset) signal += 8;
	work->signaldw += 2;
	/* カウンタを減少させる */
	/* 0になったら、終了 */
	TEST(work->ending_count, 0x7f);
	if (== 0)
		INT(0x03);

	work->ending_count--;
	if (!= 0)
		goto nextsignal;

	PUSH((int) 0);
	PUSH((int) 0x0002); // opt(close task)
	PUSH((int) 0x0040); // タスク終了
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	INT(0x03);

sig0048:
	// 再描画(他のタスクによって、持ち場が荒らされた)
	WINDOW *sig0048_win == DS:EBX, *sig0048_win2 == DS:EDI;
	(offset) sig0048_win = signal[4];
	AL = sig0048_win->sigflag;
	TEST(AL, 0x01);
	if (!= 0) {
		EDI = 2;
		TEST(AL, 0x80);
		EDX = sig0048_win->signalhead[0];
		if (!= 0)
			EDI *= 4;
		PUSH(SS);
		EDX += EDI;
		POP(ES);
		ECX = 1;
		PUSH(EDX);
		EDI = ESP;
		sendusersignal();
		POP(EAX);
		if (ZF == 0 /* error */)
			goto usersigboxfull;
		(char) [SS:ESP + 12 /* GS, ES, DS */ + 16] = 0x02; // リターン時にLlv2へ。
	} else {
		EDI = (offset) sig0048_win;
		// EBP, ESI, EDI以外は全て破壊
		drawwindow();
		drawcomponent();
		// 描画完了通知シグナル
		PUSH((int) 0);
		PUSH(sig0048_win2->slot);
		PUSH((int) 0x0144);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
		ESP += 12;
	}
	(offset) signal += 8;
	work->signaldw += 2;
//	goto nextsignal;

nextsignal:
		// モードチェンジ、window位置変更、VRAMアクセスの自由化の後には、再描画が来るのをあてにしてよい。
	} while (work->signaldw < 8);

	POP(GS);
	POP(ES);
	POP(DS);

	work->read_ptr = (offset) signal;

	// スタックを乱してリターンしてはいけない
	EAX = work->signaldw;
	LEA(EBX, work->softint_ret_buf[0]);
	work->softint_ret_buf[ 4] = EAX;
	work->softint_ret_buf[ 8] = 0x0001;
	if (work->nest == 0) {
		if (work->signalbox_read_free != 0) {
			if ((unsigned) (short) [SS:ESP + 40 /* CS */] != 0x00c7) {
				// 新規割り込み
				POP(EAX); // FS
				PUSH(GS);
				PUSH(EAX);
				PUSH(DS);
				PUSH(ES);
				ESP -= 44;
				PUSH(EAX);
				EAX = work->softint_EIP;
				ECX = work->softint_CS;
				EDX = (int) [SS:ESP + 104 /* EFLAGS */];
				(int) [SS:ESP + 16] = 0x02; // リターン時にLlv2へ。
				(int) [SS:ESP + 36 /* EIP */   ] = EAX;
				(int) [SS:ESP + 40 /* CS */    ] = ECX;
				(int) [SS:ESP + 44 /* EFLAGS */] = EDX;
				work->nest--;
			}
		}
	}
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	// エラーがない限り、ここには来ない
	INT(0x03);
//	ALIGN(4);
//wintitle_colortable:
//	asmout("wintitle_colortable DD 0008H, 0708H, 0, 040FH");
}

#define PushBF(x0,y0,x1,y1,c) PUSH(c);PUSH(y1);PUSH(x1);PUSH(y0);PUSH(x0);PUSH(ws);PUSH(op);PUSH(cn)
#define PushDrawBlock(slot,x,y,w,h,skip,ofs,sel) PUSH(sel);PUSH(ofs);PUSH(skip);PUSH(h);PUSH(w);PUSH(y);PUSH(x);PUSH(slot);PUSH(1);PUSH(0x00000414)

void near drawwindow()
{
	WINDOW *win == DS:EDI;
	unsigned int w == EAX, h == EBX, t == EBP,
		     op == ECX, ws == EDX, cn == ESI;


	PUSH(EDI);PUSH(ESI); PUSH(EBP);

	PUSH(0x20); cn = 0x0400; POP(op);		/* op = 0x20; */
	t = 0; 	ws = win->slot;
	w = win->x_size; h = win->y_size;

	PUSH(t);						/* end of command */

	#if (!defined(TMENU))
		w--;
		h--;
		PushBF(w, t, w, h, t); /* 描く順序と逆につむ */
		PushBF(t, h, w, h, t);
		PushBF(t, t, t, h, 8);
		PushBF(t, t, w, t, 8);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		ESP = EBX;
		h = win->y_size;
		w--;
		h--;
		t++; /* t = 1; */
		h--;
		PushBF(w, t, w, h, 7); /* 描く順序と逆につむ */
		PushBF(t, h, w, h, 7);
		PushBF(t, t, t, h, 15);
		PushBF(t, t, w, t, 15);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		ESP = EBX;
		w--;
		t++;
		h = win->mode0;
		w--;
		t++; /* t = 3; */
		asmout("MOVZX EBX,BYTE PTR CS:[EBX*2+wintitle_colortable+1]");
		PushBF(t, t, w, 20, h);
		h = win->y_size;
		w++;
		t--; /* t = 2; */
		h -= 3;
		PushBF(t, t, w, h, 8);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		ESP = EBX;

		// ウィンドウクローズボタンを描く
		LEA(h, [w - 3]);
		w -= 18;
		t += 3; /* t = 5; */
		PushBF(w, 18, h, 18, 0); /* 描く順序と逆につむ */
		PushBF(h, t, h, 18, 0);
		PushBF(w, t, w, 18, 15);
		PushBF(w, t, h, t, 15);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		ESP = EBX;
		LEA(h, [w + 13]);
		w++;
		t++; /* t = 6; */
		PushBF(w, t, h, 16, 8); /* 描く順序と逆につむ */
		h++;
		PushBF(h, t, h, 17, 7);
		PushBF(w, 17, h, 17, 7);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		LEA(ESP, [EBX + 4]);
	#else
		/* Window frame */
		w--;	h--;					/* w = width -1; */
		PushBF(t,t,w,t,t);								/* up */
		/* PushBF(t,h-2,w,h,t);							/  down */
		PUSH(t);PUSH(h); h-=2; PUSH(w);PUSH(h);PUSH(t);
		h--; PUSH(ws);PUSH(op);PUSH(cn);
		/* PushBF(w-2,1,w,h,t);							/  right */
		PUSH(t);PUSH(h);PUSH(w); w-=2; PUSH(1);PUSH(w);
		w--; PUSH(ws);PUSH(op);PUSH(cn);
		PushBF(t,1,t,h,t);								/* left */
		t++;					/* t=1, w=width-4, h=height-4; */

		/* window filling */
		PushBF(t,22,w,h,15);
		/* title bar down*/
		EBX = win->mode0;				/* h==EBX no longer needed :-) */
		PushBF(t,21,w,21,0);			/* line between win and bar */
		/* titlebar right */
		asmout("MOVZX EBX, byte ptr CS:[EBX*2+wintitle_colortable2]");
		/* PushBF(1,t,width-71,20,EBX); */
		PUSH(EBX); PUSH(20);PUSH(w);
		w -= 67;
		PUSH(t);PUSH(w);
		PUSH(ws);PUSH(op);PUSH(cn);
		EBX = win->mode0;
		/* titlebar mid line */
		w--;
		PushBF(w,1,w,20,0);
		/* titlebar left */
		asmout("MOVZX EBX, byte ptr CS:[EBX*2+wintitle_colortable+1]");
		w--;
		PushBF(1,t,w,20,EBX);

		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		ESP = EBX;

		/* Window close button */
		t++;t++;					/* t=3; */
		if (win->mode0 == 3) {		/* Active */
			/* 2:button rim */
			PushBF( t, 4, t,19,15);	/* left */
			PushBF( t, 3,19, 3,15);	/* up */
		}
		/* 1:button fill */
		t++;						/* t=4; */
	//	PushBF(t,t,15,16,7);
		asmout("MOV EAX,OFFSET #closebutton");
		PushDrawBlock(ws, t,t, 15,15, 1, EAX,CS);
		EBX = ESP;
		DB(0x9a); DD(0); DW(0x0017); /* GUIGUI統合shellcall */
		LEA(ESP, [EBX + 4]);
	#endif

	POP(EBP); POP(ESI);POP(EDI);
	return;

	#if (defined(TMENU))
		ALIGN(4);
closebutton:
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
		DD(0x0f000f00, 0x0f000f00, 0x0f000f00, 0x0f000f00);
		DD(0x00000000, 0x00000000, 0x00000000, 0x00000000);
	#endif
}

void near drawcomponent()
{
	WINDOW *win == DS:EDI;

	PUSH(ESI);
	PUSH(EBP);
	EDX = win->slot;
	ESP -= 56;

	// このウィンドウについているコンポーネントをサーチして、全て描画する
	LEA(EAX, win->children_back);
	ESI = win->children_next;
	if (EAX != ESI) {
		do {
			EBX = ESP;
			ESI -= 8;
			EAX = (int) [DS:ESI    ];
			ECX = (int) [DS:ESI + 4];
			if (EAX == 0x54584554 /* TEXT */) {
				// textbox
				TEXTBOX *textbox == DS:ESI;
				EAX = textbox->charset;
				(int) [DS:EBX + 28] = EAX; /* charset */
				EAX = 0;
				(short) [DS:EBX + 44] = DS;
				(int) [DS:EBX + 32] = EAX; /* base */
				(int) [DS:EBX + 48] = EAX; /* eoc */
				EAX = textbox->option;
				(int) [DS:EBX     ] = 0x0404; /* put text */
				(int) [DS:EBX +  8] = EDX;
				TEST(AH, 0xf0);
				if (== 0) {
					// 普通のテキストボックス
					int *textbox_ycnt    == DS:EBX + 52;
					PUSH(EDI);
					EBP = 0x3000; /* qword */
					TEST(AL, 0x10);
					if (!= 0)
						EBP++; /* half height */
					TEST(AL, 0x01);
					if (!= 0) {
						// EDX:win_slot, ESI:textbox
						PUSH(EBX);
						EAX = 0x0010;
						textbox_drawback();
						POP(EBX);
					}
					// バッファを参照して書き込む
				//	(int) [DS:EBX     ] = 0x0404; /* put text */
					(int) [DS:EBX +  4] = EBP; /* option */
				//	(int) [DS:EBX +  8] = EDX;
					EAX = textbox->y_size;
					EBP = textbox->x_size;
					*textbox_ycnt = EAX;
					EDX = textbox->x0;
					EAX = textbox->y0;
					LEA(EDI, (int) [textbox->buffer]);
					do {
						PUSH(ESI);
						(int) [DS:EBX + 16] = EAX; /* y0 */
						do {
							// EDX, (EAX)から書き込むルーチン
							(int) [DS:EBX + 40] = EDI;
							(int) [DS:EBX + 12] = EDX; /* x0 */
							ECX = (int) [DS:EDI + 4];
							EDI += 8;
							EAX = ECX;
							ECX >>= 16;
							EAX &= 0xffff;
							(int) [DS:EBX + 24] = ECX; /* backcolor */
							(int) [DS:EBX + 20] = EAX; /* color */
							EDX += 8; /* x */
							EBP--; /* xcnt */
							ECX = (int) [DS:EDI - 4];
							if (!= 0) {
								do {
									if (ECX != (int) [DS:EDI + 4])
										break;
									EDI += 8;
									EDX += 8; /* x */
									EBP--; /* xcnt */
								} while (!= 0);
							}
							ESI = EDX;
							ESI -= (int) [DS:EBX + 12];
							PUSH(EBX);
							ESI /= 8;
							EAX |= [DS:EBX + 24]; /* backcolor */
							(int) [DS:EBX + 36] = ESI; /* length */
							if (== 0)
								(char) [DS:EBX + 4] /* opt */ |= 0x02;
							DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
							POP(EBX);
							(char) [DS:EBX + 4] /* opt */ &= 0xfd;
						} while (EBP != 0);
						POP(ESI);
						EAX = (int) [DS:EBX + 16] /* y0 */;
						EBP = textbox->x_size;
						CL = (char) textbox->option;
						EAX += 8;
						TEST(CL, 0x10);
						if (== 0)
							EAX += 8;
						EDX = textbox->x0;
						*textbox_ycnt--;
					} while (!= 0);
					EDX = (int) [DS:EBX +  8];
					POP(EDI);
				} else {
					// wintitle
					// バッファを参照して書き込む
					ECX = 0;
				//	(int) [DS:EBX     ] = 0x0404; /* put text */
					(int) [DS:EBX +  4] = 0x3000; /* option */
				//	(int) [DS:EBX +  8] = EDX;
					CL = 24;
					EAX = win->mode0;
					(int) [DS:EBX + 12] = /* 24 */ ECX; /* x0 */
					CL = 4;
					asmout("MOVZX EAX,WORD PTR CS:[EAX*2+wintitle_colortable]");
					(int) [DS:EBX + 16] = /*  4 */ ECX; /* y0 */
					ECX = EAX;
					EAX &= 0x0f;
					ECX /= 256;
					(int) [DS:EBX + 20] = EAX; /* color */
					(int) [DS:EBX + 24] = ECX; /* backcolor */
					ECX = textbox->x_size;
					LEA(EAX, [ESI + 64]);
					(int) [DS:EBX + 36] = ECX; /* length */
					(int) [DS:EBX + 40] = EAX; /* ptr */
					DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
				}
			} else if (EAX == 0x50415247 /* GRAP */) {
				/* 本当は、モードでさらに分類する */
				GRAPHBOX *graphbox == DS:ESI;
				EAX = graphbox->x_bsize;
				ECX = graphbox->x_vsize;
				PUSH((int) 0);
				EAX -= ECX;
				PUSH(DS);
				/* ここで、必要に応じてEAXをスケールする */
				PUSH(graphbox->vbuf0);
				PUSH(EAX /* yskip */);
				PUSH(graphbox->y_vsize);
				PUSH(ECX);
				PUSH(graphbox->y0);
				PUSH(graphbox->x0);
				PUSH(EDX /* winslot */);
				PUSH((int) 0x0001);
				PUSH((int) 0x0414);
				EBX = ESP;
				DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
				ESP += 44;
			} else {
				INT(0x03);
			}
			LEA(EAX, win->children_back);
			ESI = (int) [DS:ESI + 12 /* chain_next */];
		} while (EAX != ESI);
	}
	ESP += 56;
	POP(EBP);
	POP(ESI);
	return;
}

void near textbox_drawback()
// EDX:win_slot, ESI:textbox
// EAX, ECX, EBXを破壊
{
	PUSH(EBP);
	PUSH(EAX);
	ESP -= 128 + 4;
	EBP = ESP;

	int *cmd == SS:EBP;
	TEXTBOX *textbox == DS:ESI;

	EBX = 0;
	EAX = 0x0400;
//	ECX = 0x0020;
	LEA(ECX, [EBX + 0x0020]);
	cmd[  0] = EAX /* line command */;
	cmd[  4] = ECX /* option(box-fill) */;
	cmd[  8] = EDX /* window(slot-no) */;
	cmd[ 32] = EAX /* line command */;
	cmd[ 36] = ECX /* option(box-fill) */;
	cmd[ 40] = EDX /* window(slot-no) */;
	cmd[ 64] = EAX /* line command */;
	cmd[ 68] = ECX /* option(box-fill) */;
	cmd[ 72] = EDX /* window(slot-no) */;
	cmd[ 96] = EAX /* line command */;
	cmd[100] = ECX /* option(box-fill) */;
	cmd[104] = EDX /* window(slot-no) */;
	cmd[128] = EBX /* end of command */;
	EAX = textbox->x0;
	ECX = textbox->y0;
	EAX -= 3;
	ECX -= 3;
	cmd[ 12] = EAX /* x0 */;
	cmd[ 16] = ECX /* y0 */;
	cmd[ 24] = ECX /* y1 */;
	cmd[ 44] = EAX /* x0 */;
	cmd[ 48] = ECX /* y0 */;
	cmd[ 52] = EAX /* x1 */;
	cmd[ 76] = EAX /* x0 */;
	cmd[112] = ECX /* y0 */;
	EAX = textbox->x_size;
	ECX = textbox->y_size;
	EAX *= 8;
	ECX *= 8;
	TEST(textbox->option, 0x10);
	if (== 0) {
		ECX *= 2;
	}
	EAX += textbox->x0;
	ECX += textbox->y0;
	EAX += 2;
	ECX += 2;
//	EBX = 0;
	cmd[ 20] = EAX /* x1 */;
	cmd[ 56] = ECX /* y1 */;
	cmd[ 80] = ECX /* y0 */;
	cmd[ 84] = EAX /* x1 */;
	cmd[ 88] = ECX /* y1 */;
	cmd[108] = EAX /* x0 */;
	cmd[116] = EAX /* x1 */;
	cmd[120] = ECX /* y1 */;
	LEA(EAX, [EBX + 7]);
	LEA(ECX, [EBX + 15]);
	cmd[ 28] = /*  7 */ EAX /* color */;
	cmd[ 60] = /*  7 */ EAX /* color */;
	cmd[ 92] = /* 15 */ ECX /* color */;
	cmd[124] = /* 15 */ ECX /* color */;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	EAX = cmd[ 12];
	ECX = cmd[ 16];
	EAX++;
	ECX++;
	cmd[ 12] = EAX /* x0 */;
	cmd[ 16] = ECX /* y0 */;
	cmd[ 24] = ECX /* y1 */;
	cmd[ 44] = EAX /* x0 */;
	cmd[ 48] = ECX /* y0 */;
	cmd[ 52] = EAX /* x1 */;
	cmd[ 76] = EAX /* x0 */;
	cmd[112] = ECX /* y0 */;
	EAX = cmd[116];
	ECX = cmd[120];
	EAX--;
	ECX--;
	EBX = 0;
	cmd[ 20] = EAX /* x1 */;
	cmd[ 56] = ECX /* y1 */;
	cmd[ 80] = ECX /* y0 */;
	cmd[ 84] = EAX /* x1 */;
	cmd[ 88] = ECX /* y1 */;
	cmd[108] = EAX /* x0 */;
	cmd[116] = EAX /* x1 */;
	cmd[120] = ECX /* y1 */;
	LEA(EAX, [EBX + 8]);
	cmd[ 28] = /* 0 */ EBX /* color */;
	cmd[ 60] = /* 0 */ EBX /* color */;
	cmd[ 92] = /* 8 */ EAX /* color */;
	cmd[124] = /* 8 */ EAX /* color */;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	EBX = [SS:ESP + 128 + 4];
	EAX = cmd[ 12];
	ECX = cmd[ 16];
	cmd[  4] = EBX; // opt
	EAX++;
	ECX++;
	cmd[ 12] = EAX /* x0 */;
	cmd[ 16] = ECX /* y0 */;
	EAX = cmd[116];
	ECX = cmd[120];
	EAX--;
	ECX--;
	cmd[ 20] = EAX /* x1 */;
	cmd[ 24] = ECX /* y1 */;
	EAX = textbox->backcolor;
	ECX = 0;
	cmd[ 28] = EAX /* color */;
	cmd[ 32] = ECX /* end of command */;
	EBX = ESP;
	DB(0x9a); DD(0); DW(0x0017); // GUIGUI統合shellcall
	ESP += 128 + 4;
	POP(EAX);
	POP(EBP);
	return;
}

void near lineconv()
/* EBPには本来の値より1小さい値が返るので、使う前にインクリメントすること */
{
	int x0 == EDX, y0 == EBX, x1 == EAX, y1 == ECX;
	int dx == EAX, dy == ECX, len == EBP;

	x1 -= x0;
	y1 -= y0;
	x0 <<= 16;
	y0 <<= 16;
	if (dx == 0) {
		if (dy == 0) {
			len = 0;
			return;
		}
	}
	PUSH(y0);
	PUSH(x0);
	EDX = 0; /* DIVのため */
	if (dx >= 0) {
		if (dy >= 0) {
			if (dx >= dy) {
				len = dx;
				EAX = dy;
				EAX <<= 16;
				DIV(len);
				POP(x0);
				dy = EAX;
				POP(y0);
				dx = 0x10000;
				y0 += 0x8000;
				return;
			}
		//	else {
				len = dy;
			//	EAX = dx;
				EAX <<= 16;
				DIV(len);
				POP(x0);
			//	dx = EAX;
				dy = 0x10000;
				POP(y0);
				x0 += 0x8000;
				return;
		//	}
		}
	//	else { /* dx >= 0, dy < 0 */
			dy =- dy;
			if (dx >= dy) {
				len = dx;
				EAX = dy;
				EAX <<= 16;
				DIV(len);
				dy = EAX;
				POP(x0);
				dx = 0x10000;
				POP(y0);
				dy =- dy;
				y0 += 0x8000;
				return;
			}
		//	else {
				len = dy;
			//	EAX = dx;
				EAX <<= 16;
				DIV(len);
				POP(x0);
			//	dx = EAX;
				dy = 0-0x10000;
				POP(y0);
				x0 += 0x8000;
				return;
		//	}
	//	}
	}
//	else {
		dx =- dx;
		if (dy >= 0) { /* dx < 0, dy >= 0 */
			if (dx >= dy) {
				len = dx;
				EAX = dy;
				EAX <<= 16;
				DIV(len);
				POP(x0);
				dy = EAX;
				POP(y0);
				dx = 0-0x10000;
				y0 += 0x8000;
				return;
			}
		//	else {
				len = dy;
			//	EAX = dx;
				EAX <<= 16;
				DIV(len);
			//	dx = EAX;
				POP(x0);
				dy = 0x10000;
				POP(y0);
				dx =- dx;
				x0 += 0x8000;
				return;
		//	}
		}
	//	else { /* dx < 0, dy < 0 */
			dy =- dy;
			if (dx >= dy) {
				len = dx;
				EAX = dy;
				EAX <<= 16;
				DIV(len);
				POP(x0);
				dy = EAX;
				POP(y0);
				dx = 0-0x10000;
				dy =- dy;
				y0 += 0x8000;
				return;
			}
		//	else {
				len = dy;
			//	EAX = dx;
				EAX <<= 16;
				DIV(len);
			//	dx = EAX;
				POP(x0);
				dy = 0-0x10000;
				POP(y0);
				dx =- dx;
				x0 += 0x8000;
				return;
		//	}
	//	}
//	}
}
