/*
 * $Id: sched.h,v 1.1 2003/06/06 00:15:13 tong Exp $
 *
 * ゼルダ用タスクスケジューラ
 * ＳＧＩのスケジューラを元に作成しました。
 *
 * $Log: sched.h,v $
 * Revision 1.1  2003/06/06 00:15:13  tong
 * source files for localization from Nintendo.
 *
 * Revision 3.1  2001-03-13 18:19:23+09  forest
 * All Files Revision Up!
 *
 * Revision 1.7  2001-02-01 19:50:10+09  hayakawa
 * *** empty log message ***
 *
 * Revision 1.6  2001-01-23 20:24:51+09  hayakawa
 * リセットさん関連またまた変更
 *
 * ハングアップしたスレッドが存在するか、
 * グラフかオーディオスレッドが無限ループ(１秒以上トップに戻ってこない)場合
 * やむを得ないリセットしてリセットさんを出現させないようにする。
 *
 * Revision 1.5  2000-12-21 22:09:44+09  hayakawa
 * osScSyncGraphListを追加
 *
 * Revision 1.4  2000-08-12 16:55:06+09  hayakawa
 * クラスをローカルにした
 *
 * Revision 1.3  2000-08-12 11:43:49+09  hayakawa
 * *** empty log message ***
 *
 * Revision 1.2  2000-07-10 15:06:52+09  hayakawa
 * *** empty log message ***
 *
 * Revision 1.1  1999-02-25 14:38:41+09  nii
 * Initial revision
 *
 * Revision 1.1  1998-12-02 14:56:28+09  zelda
 * Initial revision
 *
 * Revision 2.3  1998-11-09 17:41:33+09  zelda
 * *** empty log message ***
 *
 * Revision 2.2  1998-11-06 17:59:33+09  hayakawa
 * スタックを増やした
 *
 * Revision 2.1  1998-10-22 20:41:56+09  zelda
 * ＲＯＭ出しバージョン(NTSC)
 *
 * Revision 1.9  1998/04/10 11:49:01  hayakawa
 * ヌルタスクのマクロ追加
 * スタックサイズ縮小
 *
 * Revision 1.8  1998-04-01 11:47:06+09  hayakawa
 * 汎用性を考え __cplusplus を _LANGUAGE_C_PLUS_PLUS に変更
 *
 * Revision 1.7  1997/11/21  08:41:55  hayakawa
 * USE_IRQMGRを標準導入した
 *
 * Revision 1.6  1997/11/19  08:55:50  hayakawa
 * USE_IRQMGRの処理追加
 *
 * Revision 1.5  1997/11/06  07:07:22  hayakawa
 * USE_IRQMGRで条件コンパイルするようにした
 *
 * Revision 1.4  1997/03/17  01:02:03  hayakawa
 * 構造体からframebufferメンバを削除
 * gfx→graphに変更
 * 構造体にcurrent_swapbuffer、pending_swapbuffer1、pending_swapbuffer2を追加
 * osScGetIntQ、osScGetIntQをマクロ化した
 *
 * Revision 1.3  1997/03/13  11:56:40  hayakawa
 * ＳＧＩのスケジューラヘッダの取り込みしないようにした
 *
 * Revision 1.2  1997/02/12  01:14:27  hayakawa
 * Ｃ＋＋コンパイラ対応
 *
 * Revision 1.1  1997/02/06  01:18:34  hayakawa
 * Initial revision
 *
 */

#ifndef __SCHED_H_
#define __SCHED_H_

#include "ultra64.h"
#include "cfbinfo.h"
#include "irqmgr.h"		/* iramgr_t */

#ifdef _LANGUAGE_C_PLUS_PLUS
extern "C" {
#endif
#if 0
}
#endif

#define OS_SC_STACKSIZE      (0x400+0x100+0x100) /* 実績 0x144 */

#define OS_SC_RETRACE_MSG       1
#define OS_SC_DONE_MSG          2
#define OS_SC_RDP_DONE_MSG      3
#define OS_SC_PRE_NMI_MSG       4
#define OS_SC_LAST_MSG          4	/* this should have highest number */
//#define OS_SC_MAX_MESGS         8
//#define OS_SC_MAX_INT_MESGS         64
#define OS_SC_MAX_INT_MESGS         8
#define OS_SC_MAX_CMD_MESGS         8

typedef struct {
    short type;
    char  misc[30];
} OSScMsg;

typedef struct OSScTask_s {
    struct OSScTask_s   *next;          /* note: this must be first */
    u32                 state;
    u32			flags;
    cfbinfo_t		*cfbinfo;	/* used by graphics tasks */

    OSTask              list;
    OSMesgQueue         *msgQ;
    OSMesg              msg;
#ifndef _FINALROM                       /* all #ifdef items should    */
    OSTime              startTime;      /* remain at the end!!, or    */
    OSTime              totalTime;      /* possible conflict if       */
#endif                                  /* FINALROM library used with */
} OSScTask;                             /* non FINALROM code          */


#define M_NULTASK 0

/*
 * OSScTask flags:
 */
#define OS_SC_NEEDS_RDP	        0x0001	/* uses the RDP */
#define OS_SC_NEEDS_RSP	        0x0002  /* uses the RSP */
#define OS_SC_DRAM_DLIST        0x0004  /* SP & DP communicate through DRAM */
#define OS_SC_PARALLEL_TASK     0x0010	/* must be first graph task on list */
#define OS_SC_LAST_TASK	        0x0020	/* last task in queue for frame */
#define OS_SC_SWAPBUFFER        0x0040	/* swapbuffers when graph task done */

#define OS_SC_RCP_MASK		0x0003	/* mask for needs bits */
#define OS_SC_TYPE_MASK		0x0007	/* complete type mask */

/*
 * OSScClient:
 *
 * Data structure used by threads that wish to communicate to the
 * scheduling thread
 *
 */
typedef struct SCClient_s {
    struct SCClient_s   *next;  /* next client in the list      */
    OSMesgQueue         *msgQ;  /* where to send the frame msg  */
} OSScClient;

typedef struct {
    OSMesgQueue interruptQ;
    OSMesg      intBuf[OS_SC_MAX_INT_MESGS];
    OSMesgQueue cmdQ;
    OSMesg      cmdMsgBuf[OS_SC_MAX_CMD_MESGS];
    OSThread    thread;
    OSScTask    *audioListHead;
    OSScTask    *graphListHead;
    OSScTask    *audioListTail;
    OSScTask    *graphListTail;
    OSScTask    *curRSPTask;
    OSScTask    *curRDPTask;
    u32         frameCount;	/* 受信したリトレースイベントの数 */
    u8		__pad1[3];
    u8		doAudio;	/* !0:オーディオタスクがエントリされている */
    cfbinfo_t 	*current_swapbuffer; /* 表示中フレームバッファ */
    cfbinfo_t 	*pending_swapbuffer1; /* 表示待ちフレームバッファ１ */
    cfbinfo_t 	*pending_swapbuffer2; /* 表示待ちフレームバッファ２ */
    u8		__pad3[3];
    u8		firsttime;	/* 0:最初の表示時にosViBlack(FALSE)する */
    irqmgr_client_t irqclient;
} OSSched;

extern OSSched sched_class;	/* スケジューラクラス */
extern u32 graph_live_ms;    /* graphスレッドの生きてる証 */
extern u32 audio_live_ms;    /* audioスレッドの生きてる証 */

extern void osCreateScheduler(void *stack, OSPri priority);
extern OSMesgQueue *osScGetCmdQ(void);
extern void osScKickEntryMsg(void);
extern void osScCanselAudioTaskMsg(void);
extern void osScCanselGraphTaskMsg(void);
extern void osScSyncGraphList(void);
#if DEBUG
extern void sched_show(void);
#endif /* DEBUG */

#define osScGetCmdQ() (&sched_class.cmdQ)
#define osScGetIntQ() (&sched_class.interruptQ)

#if 0
{
#endif
#ifdef _LANGUAGE_C_PLUS_PLUS
} /* extern "C" */
#endif

#endif /* __SCHEDX_H_ */
