/*
 *	clipruds.c
 *
 *	パルスモーターの台形制御シーケンサ
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2015 Naoyuki Sawa
 *
 *	* Thu Apr 24 19:33:48 JST 2014 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sat Apr 26 09:27:47 JST 2014 Naoyuki Sawa
 *	- シーケンサコンパイラを作成しました。⇒clip/tool/dRudSeqC/
 *	  もう命令コード定義用マクロを使ってデータを作成する必要はありません。
 *	  スクリプトを書いて、シーケンサコンパイラでデータを作成してください。
 *	* Mon May 05 19:19:03 JST 2014 Naoyuki Sawa
 *	- cliprudc.c に停止励磁時間を追加したことに伴い、「wait stop」の条件を変更しました。
 *	  [変更前] 停止中になるまで待つ。
 *	  [変更後] 停止中,かつ,停止励磁終了するまで待つ。
 *	* Fri Nov 28 21:28:11 JST 2014 Naoyuki Sawa
 *	- パルスモーターの直接制御を追加したことに伴い、シーケンサの命令セット,命令コード,命令コード定義用マクロを変更しました。
 *	* Mon Dec 01 21:15:08 JST 2014 Naoyuki Sawa
 *	- RudSeq_Decompile()を追加しました。
 *	  逆コンパイラツール「/clip/tool/dRudSeqD」から使用します。
 *	* Fri Dec 12 21:12:36 JST 2014 Naoyuki Sawa
 *	- 条件分岐'if on','if off'を追加したことに伴い、シーケンサの命令セット,命令コード,命令コード定義用マクロを変更しました。
 *	- 条件分岐の'if on','if off'を追加したので、直接制御の'if on','if off'サフィックスは不要になりましたが、現在は残してあります。
 *	  条件分岐の'if on','if off'はシーケンサ(cliprudsモジュール)の機能であり、直接制御の'if on','if off'サフィックスはコントローラ(cliprudcモジュール)の機能であり、概念が異なるからです。
 *	  前者を用いて後者と同じ制御を行うことは可能なのですが、シーケンサを使用せずにコントローラのみを使用するケースで後者の機能が必要となることも有るかと思い、後者の機能も残してあります。
 *	  とはいえ、シーケンサの書式としては後者は不要ですので、いずれ、シーケンサの書式から、直接制御の'if on','if off'サフィックスを削除することを、検討しようと思います。
 *	  その分、直接制御のパラメータ用の、ビット数を増やせるはずです。
 *	* Fri Apr 10 21:48:53 JST 2015 Naoyuki Sawa
 *	- RudSeqCh_Stat()を追加しました。
 *	* Tue May 05 17:15:43 JST 2015 Naoyuki Sawa
 *	- RudSeqCh_PlayNo()を追加しました。
 *	* Sat Aug 01 21:04:32 JST 2015 Naoyuki Sawa
 *	- RudSeqCh_Play()が、シーケンスデータ先頭の0msタイミングに相当する処理を即実行するように、修正しました。
 *	  修正の意図は、'Fri Nov 01 17:54:30 JST 2013' にclipsnds.cのSndSeq_Play()に対して行った修正と同じです。
 */
#include "clip.h"
/****************************************************************************
 *	ローカル関数宣言
 ****************************************************************************/
static void RudSeqCh_Exec(int iRudSeqCh);
/****************************************************************************
 *	パルスモーターの台形制御シーケンサ
 ****************************************************************************/
ST_RudSeq stRudSeq;	/* 台形制御シーケンサ */
/*--------------------------------------------------------------------------*/
void RudSeq_Init(void (*fnUser)(int iRudSeqCh, int no)) {
	/* 台形制御シーケンサをクリアする。 */
	memset(&stRudSeq, 0, sizeof stRudSeq);
	/* アプリケーション定義命令処理関数を格納する。 */
	stRudSeq.fnUser = fnUser;
}
/*--------------------------------------------------------------------------*/
void RudSeqCh_Play(int iRudSeqCh, const uint16_t* pInst) {
	ST_RudSeqCh* pRudSeqCh;
	/* 台形制御シーケンサチャネルを確実に停止する。 */
	RudSeqCh_Stop(iRudSeqCh);
	/* 台形制御シーケンサチャネルを取得する。 */
	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
//{{2015/08/01修正:RudSeqCh_Play()が、シーケンスデータ先頭の0msタイミングに相当する処理を即実行するように、修正しました。
//	/* 次に実行する命令ポインタを格納する。 */
//	pRudSeqCh->pInst = pInst;
//↓2015/08/01修正:RudSeqCh_Play()が、シーケンスデータ先頭の0msタイミングに相当する処理を即実行するように、修正しました。
ENTER_CS;
	/* 次に実行する命令ポインタを格納する。 */
	pRudSeqCh->pInst = pInst;
	/* シーケンスデータ先頭の0msタイミングに相当する処理を即実行する。
	 * - こうしないと、RudSeqCh_Play()とRudSeqCh_Stop()を連続で呼び出した時、シーケンスデータ先頭の0msタイミングに相当する処理が、実行されたりされなかったりして不安定になる。
	 *   特に、シーケンスデータ先頭の0msタイミングに、原点復帰動作が設定されていた場合に、原点復帰動作が行われたり行われなかったりして、問題が顕著となる。
	 *   シーケンスデータ先頭の0msタイミングに相当する処理は、割り込みタイミングに関係無く必ず実行するのが自然であると考え、シーケンスデータ先頭の処理を即実行することにした。
	 */
	RudSeqCh_Exec(iRudSeqCh);
LEAVE_CS;
//}}2015/08/01修正:RudSeqCh_Play()が、シーケンスデータ先頭の0msタイミングに相当する処理を即実行するように、修正しました。
}
/*--------------------------------------------------------------------------*/
void RudSeqCh_Stop(int iRudSeqCh) {
	ST_RudSeqCh* pRudSeqCh;
	/* 台形制御シーケンサチャネルを取得する。 */
	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
	/* 台形制御シーケンサチャネルをクリアする。 */
	memset(pRudSeqCh, 0, sizeof(ST_RudSeqCh));
}
//------------------------------------------------------------------------------
int  RudSeqCh_Stat(int iRudSeqCh) {
	ST_RudSeqCh* pRudSeqCh;
	/* 台形制御シーケンサチャネルを取得する。 */
	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
	/* 動作中ならば1,停止中ならば0を返す。 */
	return !!pRudSeqCh->pInst;
}
/*--------------------------------------------------------------------------*/
void RudSeq_Stop() {
	int iRudSeqCh;
	/* 各台形制御シーケンサチャネルについて… */
	for(iRudSeqCh = 0; iRudSeqCh <= RudSeqCh_Max; iRudSeqCh++) {
		/* 台形制御シーケンサチャネルを停止する。 */
		RudSeqCh_Stop(iRudSeqCh);
	}
}
/*--------------------------------------------------------------------------*/
void RudSeq_Exec() {
	int iRudSeqCh;
	/* 各台形制御シーケンサチャネルについて… */
	for(iRudSeqCh = 0; iRudSeqCh <= RudSeqCh_Max; iRudSeqCh++) {
		/* 台形制御シーケンサチャネルを実行する。 */
		RudSeqCh_Exec(iRudSeqCh);
	}
}
/*==========================================================================*/
//static void RudSeqCh_Exec(int iRudSeqCh) {
//	ST_RudSeqCh* pRudSeqCh;
//	int Hi, Lo;
//	/* 台形制御シーケンサチャネルを取得する。 */
//	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
//	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
//	/* 再生中でなければ、何もしない。 */
//	if(!pRudSeqCh->pInst) { return; }
//#ifdef  WIN32
////	printf("%*s""AbsTime=%u,RelTime=%u\n",pRudSeqCh->StackLevel,"",pRudSeqCh->AbsTime,pRudSeqCh->RelTime);
//#endif//WIN32
//	for(;;) {
//		/* 命令コードを取得する。 */
//		Hi = *pRudSeqCh->pInst;
//		Lo = Hi & 0xFFF;	/* 命令コードの下位12bit */
//		Hi >>= 12;		/* 命令コードの上位 4bit */
//		/* 命令コードの上位4bitによって… */
//		switch(Hi) {
//		case 0:
//			/* 命令コードの下位12bitによって… */
//			switch(Lo) {
//			case 0: /* end */
//#ifdef  WIN32
//				printf("%*s""end\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* スタックが有れば… */
//				if(pRudSeqCh->StackLevel) {
//					/* スタックを減らす。 */
//					pRudSeqCh->StackLevel--;
//					/* Repeatスタックならば… */
//					if(pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat) {
//						/* 無限,又は,残り繰り返し回数を減らして0でなければ… */
//						if((pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat < 0) ||
//						 (--pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat)) {
//							/* 命令ポインタを設定する。 */
//							pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
//							/* スタックを増やす。 */
//							pRudSeqCh->StackLevel++;
//						}
//					/* Callスタックならば… */
//					} else {
//						/* 命令ポインタを設定する。 */
//						pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
//					}
//				/* スタックが無ければ… */
//				} else {
//					/* 再生終了する。 */
//					RudSeqCh_Stop(iRudSeqCh);
//					return; /* ここまで */
//				}
//				break;
//			case 1: /* move init */
//#ifdef  WIN32
//				printf("%*s""move init\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルの初期動作を実行する。 */
//				RudCtlCh_MoveInit(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			case 2: /* move stop */
//#ifdef  WIN32
//				printf("%*s""move stop\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルの停止動作を実行する。 */
//				RudCtlCh_Stop(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			case 3: /* wait stop */
//#ifdef  WIN32
////				printf("%*s""wait stop\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルが動作中,又は,停止励磁中ならば… */
//				if(RudCtlCh_GetSpd(iRudSeqCh) || RudCtlCh_GetStpTim(iRudSeqCh)) {				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//					goto L_EXIT; /* ここまで */
//				}
//				break;
//			default: /* user u */
//#ifdef  WIN32
//				printf("%*s""user %u\n",pRudSeqCh->StackLevel,"",Lo-4);
//#endif//WIN32
//				/* アプリケーション定義命令を実行する。 */
//				(*stRudSeq.fnUser)(iRudSeqCh, Lo-4);
//				break;
//			}
//			break;
//		case 1: /* goto */
//#ifdef  WIN32
//			printf("%*s""goto %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			/* 命令ポインタを設定する。 */
//			if(!Lo) { DIE(); } /* データバグ */									//goto命令自身へのgotoは明らかにデータバグである。
//			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
//			break;
//		case 2: /* call */
//#ifdef  WIN32
//			printf("%*s""call %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
//			/* 戻り先の命令ポインタを格納する。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;					//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
//			/* Callスタックであることを示す。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = 0;
//			/* スタックを増やす。 */
//			pRudSeqCh->StackLevel++;
//			/* 命令ポインタを設定する。 */
//			if(!Lo) { DIE(); } /* データバグ */									//call命令自身へのcallは明らかにデータバグである。
//			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
//			break;
//		case 3: /* repeat */
//#ifdef  WIN32
//			printf("%*s""repeat %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
//			/* 戻り先の命令ポインタを格納する。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;					//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
//			/* Repeatスタックの残り繰り返し回数を格納する。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = Lo ? Lo : -1/*無限*/;
//			/* スタックを増やす。 */
//			pRudSeqCh->StackLevel++;
//			break;
//		case 4: /* speed */
//#ifdef  WIN32
//			printf("%*s""speed %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			/* 分周比を設定する。 */
//			pRudSeqCh->Speed = Lo;
//			break;
//		case 5: /* move rel */
//#ifdef  WIN32
//			printf("%*s""move rel %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			/* 台形制御チャネルの動作を実行する。 */
//			RudCtlCh_MoveRel(iRudSeqCh, ((int16_t)(Lo<<4))>>4, pRudSeqCh->Speed);					//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//			break;
//		case 6: /* move abs */
//#ifdef  WIN32
//			printf("%*s""move abs %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			/* 台形制御チャネルの動作を実行する。 */
//			RudCtlCh_MoveAbs(iRudSeqCh, ((int16_t)(Lo<<4))>>4, pRudSeqCh->Speed);					//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//			break;
//		case 7: /* wait rel */
//#ifdef  WIN32
////			printf("%*s""wait rel %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			/* 直前の命令完了からの相対時間が、指定された相対時間に到達していなければ… */
//			if((unsigned)pRudSeqCh->RelTime < (unsigned)Lo) {
//				goto L_EXIT; /* ここまで */
//			}
//			break;
//		default: /* wait abs */
//#ifdef  WIN32
////			printf("%*s""wait abs %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			/* データ再生開始からの絶対時間が、指定された絶対時間に到達していなければ… */
//			if((unsigned)pRudSeqCh->AbsTime < (unsigned)(((Hi&7)<<12)|Lo)) {
//				goto L_EXIT; /* ここまで */
//			}
//			break;
//		}
//		/* 命令ポインタを進める。 */
//		pRudSeqCh->pInst++;												//end,goto,callの直後も命令ポインタが進むことに注意せよ。
//		/* 直前の命令完了からの相対時間をリセットする。 */
//		pRudSeqCh->RelTime = 0;
//	}
//L_EXIT:	/* 次回のために、データ再生開始からの絶対時間と、直前の命令完了からの相対時間を進める。
//	 * - 当関数の最初で進めるのではなく、最後で進めることに注意せよ。
//	 *   もし当関数の最初で進めると、AbsTimeが0で実行される時が無く、一回早く進んでしまう。
//	 */
//	if(pRudSeqCh->AbsTime < USHRT_MAX) { pRudSeqCh->AbsTime++; }
//	if(pRudSeqCh->RelTime < USHRT_MAX) { pRudSeqCh->RelTime++; }
//}
/*==========================================================================*/
//↓2014/11/28変更:パルスモーターの直接制御を追加したことに伴い、シーケンサの命令セット,命令コード,命令コード定義用マクロを変更しました。
/*==========================================================================*/
//static void RudSeqCh_Exec(int iRudSeqCh) {
//	ST_RudSeqCh* pRudSeqCh;
//	int Hi, Lo;
//	/* 台形制御シーケンサチャネルを取得する。 */
//	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
//	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
//	/* 再生中でなければ、何もしない。 */
//	if(!pRudSeqCh->pInst) { return; }
//#ifdef  WIN32
////	printf("%*s""AbsTime=%u,RelTime=%u\n",pRudSeqCh->StackLevel,"",pRudSeqCh->AbsTime,pRudSeqCh->RelTime);
//#endif//WIN32
//	for(;;) {
//		/* 命令コードを取得する。 */
//		Hi = *pRudSeqCh->pInst;
//		Lo = (Hi & 0xFFF);	/* 命令コードの[11: 0] */
//		Hi >>= 12;		/* 命令コードの[15:12] */
//		/* 命令コードの[15:12]によって… */
//		switch(Hi) {
//		case 0:
//			/* 命令コードの[11: 0]によって… */
//			switch(Lo) {
//			case 0: /* end */
//#ifdef  WIN32
//				printf("%*s""end\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* スタックが有れば… */
//				if(pRudSeqCh->StackLevel) {
//					/* スタックを減らす。 */
//					pRudSeqCh->StackLevel--;
//					/* Repeatスタックならば… */
//					if(pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat) {
//						/* 無限,又は,残り繰り返し回数を減らして0でなければ… */
//						if((pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat < 0) ||
//						 (--pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat)) {
//							/* 命令ポインタを設定する。 */
//							pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
//							/* スタックを増やす。 */
//							pRudSeqCh->StackLevel++;
//						}
//					/* Callスタックならば… */
//					} else {
//						/* 命令ポインタを設定する。 */
//						pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
//					}
//				/* スタックが無ければ… */
//				} else {
//					/* 再生終了する。 */
//					RudSeqCh_Stop(iRudSeqCh);
//					return; /* ここまで */
//				}
//				break;
//			case 1: /* wait stop */
//#ifdef  WIN32
////				printf("%*s""wait stop\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルが動作中,又は,停止励磁中ならば… */
//				if(RudCtlCh_GetSpd(iRudSeqCh) || RudCtlCh_GetStpTim(iRudSeqCh)) {				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//					goto L_EXIT; /* ここまで */
//				}
//				break;
//			case 2: /* move init */
//#ifdef  WIN32
//				printf("%*s""move init\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルの初期動作を実行する。 */
//				RudCtlCh_MoveInit(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			case 3: /* move stop */
//#ifdef  WIN32
//				printf("%*s""move stop\n",pRudSeqCh->StackLevel,"");
//#endif//WIN32
//				/* 台形制御チャネルの停止動作を実行する。 */
//				RudCtlCh_Stop(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			default: /* user u */
//#ifdef  WIN32
//				printf("%*s""user %u\n",pRudSeqCh->StackLevel,"",Lo-4);
//#endif//WIN32
//				/* アプリケーション定義命令を実行する。 */
//				(*stRudSeq.fnUser)(iRudSeqCh, Lo-4);
//				break;
//			}
//			break;
//		case 1: /* wait rel */
//#ifdef  WIN32
////			printf("%*s""wait rel %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			/* 直前の命令完了からの相対時間が、指定された相対時間に到達していなければ… */
//			if((unsigned)pRudSeqCh->RelTime < (unsigned)Lo) {
//				goto L_EXIT; /* ここまで */
//			}
//			break;
//		case 2: /* goto */
//#ifdef  WIN32
//			printf("%*s""goto %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			/* 命令ポインタを設定する。 */
//			if(!Lo) { DIE(); } /* データバグ */									//goto命令自身へのgotoは明らかにデータバグである。
//			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
//			break;
//		case 3: /* call */
//#ifdef  WIN32
//			printf("%*s""call %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
//#endif//WIN32
//			if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
//			/* 戻り先の命令ポインタを格納する。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;					//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
//			/* Callスタックであることを示す。 */
//			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = 0;
//			/* スタックを増やす。 */
//			pRudSeqCh->StackLevel++;
//			/* 命令ポインタを設定する。 */
//			if(!Lo) { DIE(); } /* データバグ */									//call命令自身へのcallは明らかにデータバグである。
//			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
//			break;
//		case 4:
//			Hi = Lo;
//			Lo = (Hi & 0x3FF);	/* 命令コードの[ 9: 0] */
//			Hi >>= 10;		/* 命令コードの[11:10] */
//			/* 命令コードの[11:10]によって… */
//			switch(Hi) {
//			case 0: /* repeat */
//#ifdef  WIN32
//				printf("%*s""repeat %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//				if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
//				/* 戻り先の命令ポインタを格納する。 */
//				pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;				//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
//				/* Repeatスタックの残り繰り返し回数を格納する。 */
//				pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = Lo ? Lo : -1/*無限*/;
//				/* スタックを増やす。 */
//				pRudSeqCh->StackLevel++;
//				break;
//			case 1: /* speed */
//#ifdef  WIN32
//				printf("%*s""speed %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//				/* 分周比を設定する。 */
//				pRudSeqCh->Speed = Lo;
//				break;
//			case 2: /* move rel */
//#ifdef  WIN32
//				printf("%*s""move rel %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6);
//#endif//WIN32
//				/* 台形制御チャネルの動作を実行する。 */
//				RudCtlCh_MoveRel(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed);				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			default: /* move abs */
//#ifdef  WIN32
//				printf("%*s""move abs %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6);
//#endif//WIN32
//				/* 台形制御チャネルの動作を実行する。 */
//				RudCtlCh_MoveAbs(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed);				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//				break;
//			}
//			break;
//		case 5: /* move direct if on */
//		case 6: /* move direct if off */
//		case 7: /* move direct always */
//#ifdef  WIN32
//			{static const char* TBL_CondIf[]  ={""," if on"     ," if off"    ," always"    };
//			 static const char* TBL_CondWhen[]={""," until rise"," until fall"," until edge"};
//			 printf("%*s""move direct %d%s%s\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6,TBL_CondIf[(Lo>>12)&3],TBL_CondWhen[(Lo>>10)&3]);}
//#endif//WIN32
//			/* 台形制御チャネルの動作を実行する。 */
//			RudCtlCh_MoveDirect(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed, Hi&3, (Lo>>10)&3);		//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
//			break;
//		default: /* wait abs */
//#ifdef  WIN32
////			printf("%*s""wait abs %u\n",pRudSeqCh->StackLevel,"",Lo);
//#endif//WIN32
//			/* データ再生開始からの絶対時間が、指定された絶対時間に到達していなければ… */
//			if((unsigned)pRudSeqCh->AbsTime < (unsigned)(((Hi&7)<<12)|Lo)) {
//				goto L_EXIT; /* ここまで */
//			}
//			break;
//		}
//		/* 命令ポインタを進める。 */
//		pRudSeqCh->pInst++;												//end,goto,callの直後も命令ポインタが進むことに注意せよ。
//		/* 直前の命令完了からの相対時間をリセットする。 */
//		pRudSeqCh->RelTime = 0;
//	}
//L_EXIT:	/* 次回のために、データ再生開始からの絶対時間と、直前の命令完了からの相対時間を進める。
//	 * - 当関数の最初で進めるのではなく、最後で進めることに注意せよ。
//	 *   もし当関数の最初で進めると、AbsTimeが0で実行される時が無く、一回早く進んでしまう。
//	 */
//	if(pRudSeqCh->AbsTime < USHRT_MAX) { pRudSeqCh->AbsTime++; }
//	if(pRudSeqCh->RelTime < USHRT_MAX) { pRudSeqCh->RelTime++; }
//}
/*==========================================================================*/
//↓2014/12/12変更:条件分岐'if on','if off'を追加したことに伴い、シーケンサの命令セット,命令コード,命令コード定義用マクロを変更しました。
/*==========================================================================*/
static void RudSeqCh_Exec(int iRudSeqCh) {
	ST_RudSeqCh* pRudSeqCh;
	int Hi, Lo;
	/* 台形制御シーケンサチャネルを取得する。 */
	if((unsigned)iRudSeqCh > RudSeqCh_Max) { DIE(); }
	pRudSeqCh = &stRudSeq.TBL_RudSeqCh[iRudSeqCh];
	/* 再生中でなければ、何もしない。 */
	if(!pRudSeqCh->pInst) { return; }
#ifdef  WIN32
//	printf("%*s""AbsTime=%u,RelTime=%u\n",pRudSeqCh->StackLevel,"",pRudSeqCh->AbsTime,pRudSeqCh->RelTime);
#endif//WIN32
	for(;;) {
		/* 命令コードを取得する。 */
		Hi = *pRudSeqCh->pInst;
		Lo = (Hi & 0xFFF);	/* 命令コードの[11: 0] */
		Hi >>= 12;		/* 命令コードの[15:12] */
		/* 命令コードの[15:12]によって… */
		switch(Hi) {
		case 0:
			/* 命令コードの[11: 0]によって… */
			switch(Lo) {
			default: /* user u */
#ifdef  WIN32
				printf("%*s""user %u\n",pRudSeqCh->StackLevel,"",Lo);
#endif//WIN32
				/* アプリケーション定義命令を実行する。 */
				(*stRudSeq.fnUser)(iRudSeqCh, Lo);
				break;
			case 0x0FFA: /* if on */
#ifdef  WIN32
				printf("%*s""if on\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* センサ安定状態がOn でなければ次の命令を飛ばす。 */
				if(!RudCtlCh_Get(iRudSeqCh)->Sns) {								//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
					pRudSeqCh->pInst += 2 - 1/*共通処理の「+1」を相殺*/;
				}
				break;
			case 0x0FFB: /* if off */
#ifdef  WIN32
				printf("%*s""if off\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* センサ安定状態がOffでなければ次の命令を飛ばす。 */
				if( RudCtlCh_Get(iRudSeqCh)->Sns) {								//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
					pRudSeqCh->pInst += 2 - 1/*共通処理の「+1」を相殺*/;
				}
				break;
			case 0x0FFC: /* wait stop */
#ifdef  WIN32
//				printf("%*s""wait stop\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* 台形制御チャネルが動作中,又は,停止励磁中ならば… */
				if(RudCtlCh_GetSpd(iRudSeqCh) || RudCtlCh_GetStpTim(iRudSeqCh)) {				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
					goto L_EXIT; /* ここまで */
				}
				break;
			case 0x0FFD: /* move stop */
#ifdef  WIN32
				printf("%*s""move stop\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* 台形制御チャネルの停止動作を実行する。 */
				RudCtlCh_Stop(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
				break;
			case 0x0FFE: /* move init */
#ifdef  WIN32
				printf("%*s""move init\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* 台形制御チャネルの初期動作を実行する。 */
				RudCtlCh_MoveInit(iRudSeqCh);									//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
				break;
			case 0x0FFF: /* end */
#ifdef  WIN32
				printf("%*s""end\n",pRudSeqCh->StackLevel,"");
#endif//WIN32
				/* スタックが有れば… */
				if(pRudSeqCh->StackLevel) {
					/* スタックを減らす。 */
					pRudSeqCh->StackLevel--;
					/* Repeatスタックならば… */
					if(pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat) {
						/* 無限,又は,残り繰り返し回数を減らして0でなければ… */
						if((pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat < 0) ||
						 (--pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat)) {
							/* 命令ポインタを設定する。 */
							pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
							/* スタックを増やす。 */
							pRudSeqCh->StackLevel++;
						}
					/* Callスタックならば… */
					} else {
						/* 命令ポインタを設定する。 */
						pRudSeqCh->pInst = pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst;
					}
				/* スタックが無ければ… */
				} else {
					/* 再生終了する。 */
					RudSeqCh_Stop(iRudSeqCh);
					return; /* ここまで */
				}
				break;
			}
			break;
		case 1: /* wait rel */
#ifdef  WIN32
//			printf("%*s""wait rel %u\n",pRudSeqCh->StackLevel,"",Lo);
#endif//WIN32
			/* 直前の命令完了からの相対時間が、指定された相対時間に到達していなければ… */
			if((unsigned)pRudSeqCh->RelTime < (unsigned)Lo) {
				goto L_EXIT; /* ここまで */
			}
			break;
		case 2: /* goto */
#ifdef  WIN32
			printf("%*s""goto %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
#endif//WIN32
			/* 命令ポインタを設定する。 */
			if(!Lo) { DIE(); } /* データバグ */									//goto命令自身へのgotoは明らかにデータバグである。
			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
			break;
		case 3: /* call */
#ifdef  WIN32
			printf("%*s""call %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<4))>>4);
#endif//WIN32
			if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
			/* 戻り先の命令ポインタを格納する。 */
			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;					//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
			/* Callスタックであることを示す。 */
			pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = 0;
			/* スタックを増やす。 */
			pRudSeqCh->StackLevel++;
			/* 命令ポインタを設定する。 */
			if(!Lo) { DIE(); } /* データバグ */									//call命令自身へのcallは明らかにデータバグである。
			pRudSeqCh->pInst += (((int16_t)(Lo<<4))>>4) - 1/*共通処理の「+1」を相殺*/;
			break;
		case 4:
			Hi = Lo;
			Lo = (Hi & 0x3FF);	/* 命令コードの[ 9: 0] */
			Hi >>= 10;		/* 命令コードの[11:10] */
			/* 命令コードの[11:10]によって… */
			switch(Hi) {
			case 0: /* repeat */
#ifdef  WIN32
				printf("%*s""repeat %u\n",pRudSeqCh->StackLevel,"",Lo);
#endif//WIN32
				if((unsigned)pRudSeqCh->StackLevel >= RudSeqCh_StackSize) { DIE(); }	/* RudSeqCh_StackSizeを調整せよ */
				/* 戻り先の命令ポインタを格納する。 */
				pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].pInst = pRudSeqCh->pInst;				//「〜=pRudSeqCh->pInst+1/*次の命令*/;」ではないことに注意せよ。「+1」は戻り時のendの実行後の共通処理で行われるから。
				/* Repeatスタックの残り繰り返し回数を格納する。 */
				pRudSeqCh->TBL_Stack[pRudSeqCh->StackLevel].Repeat = Lo ? Lo : -1/*無限*/;
				/* スタックを増やす。 */
				pRudSeqCh->StackLevel++;
				break;
			case 1: /* speed */
#ifdef  WIN32
				printf("%*s""speed %u\n",pRudSeqCh->StackLevel,"",Lo);
#endif//WIN32
				/* 分周比を設定する。 */
				pRudSeqCh->Speed = Lo;
				break;
			case 2: /* move rel */
#ifdef  WIN32
				printf("%*s""move rel %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6);
#endif//WIN32
				/* 台形制御チャネルの動作を実行する。 */
				RudCtlCh_MoveRel(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed);				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
				break;
			default: /* move abs */
#ifdef  WIN32
				printf("%*s""move abs %d\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6);
#endif//WIN32
				/* 台形制御チャネルの動作を実行する。 */
				RudCtlCh_MoveAbs(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed);				//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
				break;
			}
			break;
		case 5: /* move direct if on */
		case 6: /* move direct if off */
		case 7: /* move direct always */
#ifdef  WIN32
			{static const char* TBL_CondIf[]  ={""," if on"     ," if off"    ," always"    };
			 static const char* TBL_CondWhen[]={""," until rise"," until fall"," until edge"};
			 printf("%*s""move direct %d%s%s\n",pRudSeqCh->StackLevel,"",((int16_t)(Lo<<6))>>6,TBL_CondIf[(Lo>>12)&3],TBL_CondWhen[(Lo>>10)&3]);}
#endif//WIN32
			/* 台形制御チャネルの動作を実行する。 */
			RudCtlCh_MoveDirect(iRudSeqCh, ((int16_t)(Lo<<6))>>6, pRudSeqCh->Speed, Hi&3, (Lo>>10)&3);		//（台形制御チャネル番号＝台形制御シーケンサチャネル番号）という前提
			break;
		default: /* wait abs */
#ifdef  WIN32
//			printf("%*s""wait abs %u\n",pRudSeqCh->StackLevel,"",Lo);
#endif//WIN32
			/* データ再生開始からの絶対時間が、指定された絶対時間に到達していなければ… */
			if((unsigned)pRudSeqCh->AbsTime < (unsigned)(((Hi&7)<<12)|Lo)) {
				goto L_EXIT; /* ここまで */
			}
			break;
		}
		/* 命令ポインタを進める。 */
		pRudSeqCh->pInst++;												//end,goto,callの直後も命令ポインタが進むことに注意せよ。
		/* 直前の命令完了からの相対時間をリセットする。 */
		pRudSeqCh->RelTime = 0;
	}
L_EXIT:	/* 次回のために、データ再生開始からの絶対時間と、直前の命令完了からの相対時間を進める。
	 * - 当関数の最初で進めるのではなく、最後で進めることに注意せよ。
	 *   もし当関数の最初で進めると、AbsTimeが0で実行される時が無く、一回早く進んでしまう。
	 */
	if(pRudSeqCh->AbsTime < USHRT_MAX) { pRudSeqCh->AbsTime++; }
	if(pRudSeqCh->RelTime < USHRT_MAX) { pRudSeqCh->RelTime++; }
}
/*==========================================================================*/
/****************************************************************************
 *	dRudSeqC.exeが出力したバイナリ形式を扱うためのユーティリティ関数
 ****************************************************************************/
#ifdef  USE_RUDDEF_BIN
void RudSeqCh_PlayNo(int iRudSeqCh, const void* pRudDefBin, int iRudSeqNo) {
	const int* const TBL_RudSeqNo = pRudDefBin;							//バイナリの先頭にアドレステーブルが有る。アドレスはデータ本体(HALF配列)のインデクスである。
	const int nRudSeqNo = TBL_RudSeqNo[0];								//アドレステーブルの先頭[0]に要素数が入っている。要素数はそれ自身([0])も含む。
	const unsigned short* const TBL_RudSeq = (const unsigned short*)&TBL_RudSeqNo[nRudSeqNo];	//アドレステーブルの直後からデータ本体(HALF配列)が開始する。
	if((iRudSeqNo <= 0) || (iRudSeqNo >= nRudSeqNo)) { DIE(); }
	RudSeqCh_Play(iRudSeqCh, &TBL_RudSeq[TBL_RudSeqNo[iRudSeqNo]]);
}
#endif//USE_RUDDEF_BIN
#ifdef  WIN32
/****************************************************************************
 *	逆コンパイラ
 ****************************************************************************/
/*==========================================================================*/
//void RudSeq_Decompile(const uint16_t TBL_Data[/*iDataLen*/], int iDataLen) {
//	int iData, Hi, Lo;
//	for(iData = 0; iData < iDataLen; iData++) {
//		printf("%04X %04X ", iData, TBL_Data[iData]);										//Addr Code
//		/* 命令コードを取得する。 */
//		Hi = TBL_Data[iData];
//		Lo = (Hi & 0xFFF);	/* 命令コードの[11: 0] */
//		Hi >>= 12;		/* 命令コードの[15:12] */
//		/* 命令コードの[15:12]によって… */
//		switch(Hi) {
//		case 0:
//			/* 命令コードの[11: 0]によって… */
//			switch(Lo) {
//			case 0: /* end */
//				printf("%s", "end");											//Inst
//				break;
//			case 1: /* wait stop */
//				printf("%s", "wait stop");										//Inst
//				break;
//			case 2: /* move init */
//				printf("%s", "move init");										//Inst
//				break;
//			case 3: /* move stop */
//				printf("%s", "move stop");										//Inst
//				break;
//			default: /* user u */
//				printf("%s %u", "user", Lo-4);										//Inst
//				break;
//			}
//			break;
//		case 1: /* wait rel */
//			printf("%s %u", "wait rel", Lo);										//Inst
//			break;
//		case 2: /* goto */
//			printf("%s %d", "goto", ((int16_t)(Lo<<4))>>4);									//Inst
//			printf(" #%04X", iData+(((int16_t)(Lo<<4))>>4));								//Comment
//			break;
//		case 3: /* call */
//			printf("%s %d", "call", ((int16_t)(Lo<<4))>>4);									//Inst
//			printf(" #%04X", iData+(((int16_t)(Lo<<4))>>4));								//Comment
//			break;
//		case 4:
//			Hi = Lo;
//			Lo = (Hi & 0x3FF);	/* 命令コードの[ 9: 0] */
//			Hi >>= 10;		/* 命令コードの[11:10] */
//			/* 命令コードの[11:10]によって… */
//			switch(Hi) {
//			case 0: /* repeat */
//				printf("%s %u", "repeat", Lo);										//Inst
//				break;
//			case 1: /* speed */
//				printf("%s %u", "speed", Lo);										//Inst
//				break;
//			case 2: /* move rel */
//				printf("%s %d", "move rel", ((int16_t)(Lo<<6))>>6);							//Inst
//				break;
//			default: /* move abs */
//				printf("%s %d", "move abs", ((int16_t)(Lo<<6))>>6);							//Inst
//				break;
//			}
//			break;
//		case 5: /* move direct if on */
//		case 6: /* move direct if off */
//		case 7: /* move direct always */
//			{static const char* TBL_CondIf[]  ={""," if on"     ," if off"    ," always"    };
//			 static const char* TBL_CondWhen[]={""," until rise"," until fall"," until edge"};
//			 printf("%s %d%s%s", "move direct", ((int16_t)(Lo<<6))>>6, TBL_CondIf[(Lo>>12)&3], TBL_CondWhen[(Lo>>10)&3]);}	//Inst
//			break;
//		default: /* wait abs */
//			printf("%s %u", "wait abs", ((Hi&7)<<12)|Lo);									//Inst
//			break;
//		}
//		printf("\n");														//改行
//	}
//}
/*==========================================================================*/
//↓2014/12/12変更:条件分岐'if on','if off'を追加したことに伴い、シーケンサの命令セット,命令コード,命令コード定義用マクロを変更しました。
/*==========================================================================*/
void RudSeq_Decompile(const uint16_t TBL_Data[/*iDataLen*/], int iDataLen) {
	int iData, Hi, Lo;
	for(iData = 0; iData < iDataLen; iData++) {
		printf("%04X %04X ", iData, TBL_Data[iData]);										//Addr Code
		/* 命令コードを取得する。 */
		Hi = TBL_Data[iData];
		Lo = (Hi & 0xFFF);	/* 命令コードの[11: 0] */
		Hi >>= 12;		/* 命令コードの[15:12] */
		/* 命令コードの[15:12]によって… */
		switch(Hi) {
		case 0:
			/* 命令コードの[11: 0]によって… */
			switch(Lo) {
			default: /* user u */
				printf("%s %u", "user", Lo);										//Inst
				break;
			case 0x0FFA: /* if on */
				printf("%s", "if on");											//Inst
				break;
			case 0x0FFB: /* if off */
				printf("%s", "if off");											//Inst
				break;
			case 0x0FFC: /* wait stop */
				printf("%s", "wait stop");										//Inst
				break;
			case 0x0FFD: /* move stop */
				printf("%s", "move stop");										//Inst
				break;
			case 0x0FFE: /* move init */
				printf("%s", "move init");										//Inst
				break;
			case 0x0FFF: /* end */
				printf("%s", "end");											//Inst
				break;
			}
			break;
		case 1: /* wait rel */
			printf("%s %u", "wait rel", Lo);										//Inst
			break;
		case 2: /* goto */
			printf("%s %d", "goto", ((int16_t)(Lo<<4))>>4);									//Inst
			printf(" #%04X", iData+(((int16_t)(Lo<<4))>>4));								//Comment
			break;
		case 3: /* call */
			printf("%s %d", "call", ((int16_t)(Lo<<4))>>4);									//Inst
			printf(" #%04X", iData+(((int16_t)(Lo<<4))>>4));								//Comment
			break;
		case 4:
			Hi = Lo;
			Lo = (Hi & 0x3FF);	/* 命令コードの[ 9: 0] */
			Hi >>= 10;		/* 命令コードの[11:10] */
			/* 命令コードの[11:10]によって… */
			switch(Hi) {
			case 0: /* repeat */
				printf("%s %u", "repeat", Lo);										//Inst
				break;
			case 1: /* speed */
				printf("%s %u", "speed", Lo);										//Inst
				break;
			case 2: /* move rel */
				printf("%s %d", "move rel", ((int16_t)(Lo<<6))>>6);							//Inst
				break;
			default: /* move abs */
				printf("%s %d", "move abs", ((int16_t)(Lo<<6))>>6);							//Inst
				break;
			}
			break;
		case 5: /* move direct if on */
		case 6: /* move direct if off */
		case 7: /* move direct always */
			{static const char* TBL_CondIf[]  ={""," if on"     ," if off"    ," always"    };
			 static const char* TBL_CondWhen[]={""," until rise"," until fall"," until edge"};
			 printf("%s %d%s%s", "move direct", ((int16_t)(Lo<<6))>>6, TBL_CondIf[(Lo>>12)&3], TBL_CondWhen[(Lo>>10)&3]);}	//Inst
			break;
		default: /* wait abs */
			printf("%s %u", "wait abs", ((Hi&7)<<12)|Lo);									//Inst
			break;
		}
		printf("\n");														//改行
	}
}
/*==========================================================================*/
#endif//WIN32
#if 0
/****************************************************************************
 *	サンプルデータ
 ****************************************************************************/
//□ｻﾝﾌﾟﾙﾃﾞｰﾀ1
const uint16_t TBL_Inst1[]={
RudSeq_Inst_move_init,		//初期動作を行う｡
RudSeq_Inst_wait_abs(1000),	//ﾃﾞｰﾀ再生開始からの絶対時間が1秒以上になるまで待つ｡
RudSeq_Inst_speed(5),		//分周比を設定する｡これ以降のmoveに対して適用される｡
RudSeq_Inst_move_abs(100),	//絶対位置への動作を開始する｡
RudSeq_Inst_wait_stop,		//動作が終了するまで待つ｡
RudSeq_Inst_move_rel(-500),	//相対位置への動作を開始する｡
RudSeq_Inst_wait_rel(200),	//直前の命令完了からの相対時間が200ﾐﾘ秒以上になるまで待つ｡
RudSeq_Inst_move_stop,		//(動作が完了していなければ､)停止動作を開始する｡
RudSeq_Inst_wait_abs(5000),	//ﾃﾞｰﾀ再生開始からの絶対時間が5秒以上になるまで待つ｡
RudSeq_Inst_move_abs(0),	//原点位置への動作を開始する｡
RudSeq_Inst_end,		//再生終了する｡(動作が完了していなければ、動作は継続する｡)
};
//↓実行結果
//move init
//speed 5
//move abs 100
//move rel -500
//move stop
//move abs 0
//end
/*--------------------------------------------------------------------------*/
//□ｻﾝﾌﾟﾙﾃﾞｰﾀ2
const uint16_t TBL_Inst2[]={
RudSeq_Inst_goto(2),		//この命令の位置を基準とした相対位置で､+2の命令へ分岐する｡
RudSeq_Inst_move_init,		//この命令は実行されない｡
//gotoの飛び先
RudSeq_Inst_repeat(2),		//2回繰り返しを開始する｡
RudSeq_Inst_call(3),		//この命令の位置を基準とした相対位置で､+3の命令を呼び出す｡
RudSeq_Inst_end,		//2回繰り返す｡このendは､repeatに対応するendである｡
RudSeq_Inst_end,		//再生終了する｡(動作が完了していなければ、動作は継続する｡)
//callの呼び先
RudSeq_Inst_move_rel(10),	//相対位置への動作を開始する｡
RudSeq_Inst_wait_stop,		//動作が終了するまで待つ｡
RudSeq_Inst_move_rel(-10),	//相対位置への動作を開始する｡
RudSeq_Inst_wait_stop,		//動作が終了するまで待つ｡
RudSeq_Inst_end,		//呼び出し元へ戻る｡このendは､callに対応するendである｡
};
//↓実行結果
//goto 2
//repeat 2
// call 3
//  move rel 10
//  move rel -10
//  end
// end
// call 3
//  move rel 10
//  move rel -10
//  end
// end
//end
/*--------------------------------------------------------------------------*/
#endif
