#ifndef _WAV_KERNEL_H_
#define _WAV_KERNEL_H_

#include <Time.h>

#define INTERRUPT_CLI asm cli
#define INTERRUPT_STI asm sti


#if defined(LANRY_COMPANY)
	#define MICRODELAY_TIME_1   298u
	#define MICRODELAY_TIME_2   596u
	#define MICRODELAY_TIME_3   894u
	#define MICRODELAY_TIME_4  1193u
	#define MICRODELAY_TIME_5  1491u
	#define MICRODELAY_TIME_6  1789u
	#define MICRODELAY_TIME_7  2088u
	#define MICRODELAY_TIME_8  2386u
	#define MICRODELAY_TIME_9  2684u
	#define MICRODELAY_TIME_10  2982u
	#define MICRODELAY_TIME_11  3281u
	#define MICRODELAY_TIME_12  3579u
	#define MICRODELAY_TIME_13  3877u
	#define MICRODELAY_TIME_14  4176u
	#define MICRODELAY_TIME_15  4474u
	#define MICRODELAY_TIME_16  4772u
	#define MICRODELAY_TIME_17  5071u
	#define MICRODELAY_TIME_18  5369u
	#define MICRODELAY_TIME_19  5667u
	#define MICRODELAY_TIME_20  5965u
	#define MICRODELAY_TIME_21  6264u
	#define MICRODELAY_TIME_22  6562u
	#define MICRODELAY_TIME_23  6860u
	#define MICRODELAY_TIME_24  7159u
	#define MICRODELAY_TIME_25  7457u
	#define MICRODELAY_TIME_26  7755u
	#define MICRODELAY_TIME_27  8053u
	#define MICRODELAY_TIME_28  8352u
	#define MICRODELAY_TIME_29  8650u
	#define MICRODELAY_TIME_30  8948u
	#define MICRODELAY_TIME_31  9247u
	#define MICRODELAY_TIME_32  9545u
	#define MICRODELAY_TIME_33  9843u
	#define MICRODELAY_TIME_34 10142u
	#define MICRODELAY_TIME_35 10440u
	#define MICRODELAY_TIME_36 10738u
	#define MICRODELAY_TIME_37 11036u
	#define MICRODELAY_TIME_38 11335u
	#define MICRODELAY_TIME_39 11633u
	#define MICRODELAY_TIME_40 11931u
	#define MICRODELAY_TIME_41 12230u
	#define MICRODELAY_TIME_42 12528u
	#define MICRODELAY_TIME_43 12826u
	#define MICRODELAY_TIME_44 13124u
	#define MICRODELAY_TIME_45 13423u
	#define MICRODELAY_TIME_46 13721u
	#define MICRODELAY_TIME_47 14019u
	#define MICRODELAY_TIME_48 14318u
	#define MICRODELAY_TIME_49 14616u
	#define MICRODELAY_TIME_50 14914u
#else
	#define MICRODELAY_TIME_1   1193u
	#define MICRODELAY_TIME_2   2386u
	#define MICRODELAY_TIME_3   3579u
	#define MICRODELAY_TIME_4   4773u
	#define MICRODELAY_TIME_5   5966u
	#define MICRODELAY_TIME_6   7159u
	#define MICRODELAY_TIME_7   8352u
	#define MICRODELAY_TIME_8   9545u
	#define MICRODELAY_TIME_9   10738u
	#define MICRODELAY_TIME_10  11932u
	#define MICRODELAY_TIME_11  (4u*3281u)
	#define MICRODELAY_TIME_12  (4u*3579u)
	#define MICRODELAY_TIME_13  (4u*3877u)
	#define MICRODELAY_TIME_14  (4u*4176u)
	#define MICRODELAY_TIME_15  (4u*4474u)
	#define MICRODELAY_TIME_16  (4u*4772u)
	#define MICRODELAY_TIME_17  (4u*5071u)
	#define MICRODELAY_TIME_18  (4u*5369u)
	#define MICRODELAY_TIME_19  (4u*5667u)
	#define MICRODELAY_TIME_20  23864u
	#define MICRODELAY_TIME_21  (4u*6264u)
	#define MICRODELAY_TIME_22  (4u*6562u)
	#define MICRODELAY_TIME_23  (4u*6860u)
	#define MICRODELAY_TIME_24  (4u*7159u)
	#define MICRODELAY_TIME_25  (4u*7457u)
	#define MICRODELAY_TIME_26  (4u*7755u)
	#define MICRODELAY_TIME_27  (4u*8053u)
	#define MICRODELAY_TIME_28  (4u*8352u)
	#define MICRODELAY_TIME_29  (4u*8650u)
	#define MICRODELAY_TIME_30  35795u
	#define MICRODELAY_TIME_31  (4u*9247u)
	#define MICRODELAY_TIME_32  (4u*9545u)
	#define MICRODELAY_TIME_33  (4u*9843u)
	#define MICRODELAY_TIME_34 (4u*10142u)
	#define MICRODELAY_TIME_35 (4u*10440u)
	#define MICRODELAY_TIME_36 (4u*10738u)
	#define MICRODELAY_TIME_37 (4u*11036u)
	#define MICRODELAY_TIME_38 (4u*11335u)
	#define MICRODELAY_TIME_39 (4u*11633u)
	#define MICRODELAY_TIME_40 47724u
	#define MICRODELAY_TIME_41 (4u*12230u)
	#define MICRODELAY_TIME_42 (4u*12528u)
	#define MICRODELAY_TIME_43 (4u*12826u)
	#define MICRODELAY_TIME_44 (4u*13124u)
	#define MICRODELAY_TIME_45 (4u*13423u)
	#define MICRODELAY_TIME_46 (4u*13721u)
	#define MICRODELAY_TIME_47 (4u*14019u)
	#define MICRODELAY_TIME_48 (4u*14318u)
	#define MICRODELAY_TIME_49 (4u*14616u)
	#define MICRODELAY_TIME_50 59659u

#endif

//This is the status of process
#define PROCESS_STATE_EMPTY       0
#define PROCESS_STATE_CREATE      1
#define PROCESS_STATE_READY       2
#define PROCESS_STATE_RUNNING     3
#define PROCESS_STATE_SWAP        4
#define PROCESS_STATE_SLEEP       5
#define PROCESS_STATE_EXIT        6
#define PROCESS_STATE_SUSPEND     7
#define PROCESS_STATE_WAITOBJECT  8

//This is the priority of Process
#define IDLE_PRIORITY_CLASS           (29 - 1)
#define NORMAL_PRIORITY_CLASS         (30 - 1)
#define HIGH_RIORITY_CLASS            (31 - 1)
#define REALTIME_PRIORITY_CLASS       (32 - 1)

//This is the priority of Thread
#define THREAD_PRIORITY_CRITICAL      (1 - 1)
#define THREAD_PRIORITY_HIGHEST       (2 - 1)
#define THREAD_PRIORITY_ABOVE_NORMAL  (3 - 1)
#define THREAD_PRIORITY_NORMAL        (4 - 1)
#define THREAD_PRIORITY_BELOW_NORMAL  (5 - 1)
#define THREAD_PRIORITY_LOWEST        (27 - 1)
#define THREAD_PRIORITY_IDLE          (28 - 1)


#define SYNOBJECT_NULL    0
#define SYNOBJECT_CRI     1  //临界
#define SYNOBJECT_SEM     2  //信号量
#define SYNOBJECT_MUTEX   3  //互斥
#define SYNOBJECT_EVENT   4  //事件
#define SYNOBJECT_MAILBOX 5  //邮箱
#define SYNOBJECT_PIPE    6  //管道


#define MAX_SYNOBJECT_COUNT 10
#define MAX_PROCESS_COUNT   10
#define DEFAULT_STACK_SIZE (4u*1024u)

//安全属性
typedef struct _SECURITY_ATTRIBUTES { // sa 
    DWORD  nLength; 
    LPVOID lpSecurityDescriptor; 
    BOOL   bInheritHandle; 
} SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; 


#define CRITICAL_SECTION            ULONG
typedef CRITICAL_SECTION*           LPCRITICAL_SECTION;


//同步对象属性
struct SYNOBJECT
{
	//类型
	WORD wStyle;
	//安全属性
	SECURITY_ATTRIBUTES mSecurityAttrib;

    union
    {
		BOOL   bCriticalSection; //临界
        BOOL   bMutex; //互斥
        WORD   wSemCount;  //信号量
        BOOL   bEvent; //事件
        void*  pMailBox; //邮箱
		void*  pPipe; //管道
    }object;

	union
	{
		BOOL bManualReset; //事件
		long lMaximumCount;//信号量
		DWORD dwSpinCount; //临界
		
	}attrib;
	//线程占用信息
    DWORD dwTask;
	DWORD dwUserCount;
	//用户信息
    void* pUser;
};



//任务时钟属性
struct TIME_KERNEL
{
	int nHour;
	int nMin;
	int nSec;
	int nHun;
	DWORD dwDate;
};


//PCB控制块
struct WAVE_PROCESS_TCB
{
	//任务统计
    DWORD dwCounter;
	//任务存在标志
	BOOL bExist;

	//CPU寄存器
	WORD wBp;
	WORD wDi;
	WORD wSi;
	WORD wDs;
	WORD wEs;
	WORD wDx;
	WORD wCx;
	WORD wBx;
	WORD wAx;
	WORD wIp;
	WORD wCs;
	WORD wFlags;

	WORD wSs;
	WORD wSp;
	//FPU的寄存器
    BYTE by80x87[94];

	//推栈指针
	void* pStack;
	//推栈尺寸
    WORD wStackSize;
	//回调函数
	int  (*pFc)(DWORD);
	//回调函数参数
	DWORD dwParam;

	//任务状态	
	DWORD   dwState;
	//任务时间
	TIME_KERNEL mTimeKernel;
	//任务优先级
    DWORD dwPriority;
	//占用的同步对象
    DWORD dwTask;
};

//初始化多任务管理器
BOOL KernelInitProcess();
//退同多任务管理器
BOOL KernelCloseProcess();

//void KernelOpenLoop_Hardware();
//void KernelCloseLoop_Hardware();
//void KernelSaveLoop_Hardware();
//WORD KernelSaveLoop();
//void KernelRestoreLoop(WORD wKernel);
//WORD KernelSaveAndCloseLoop();

//调度器加锁（软件）
void AfxKernelLock_Software();
//调度器解锁（软件）
void AfxKernelUnlock_Software();
//调度器加锁（硬件）
void AfxKernelLock_Hardware();
//调度器解锁（硬件）
void AfxKernelUnlock_Hardware();

//启动一个进程
int  AfxBeginProcess(int  (*pFc)(DWORD) , DWORD dwParam,
	WORD wStackSize= DEFAULT_STACK_SIZE);
//结束一个进程
int  AfxEndProcess(int hProcess);
//获得当前进程的进程号
int  AfxGetTaskNo();
//挂起指定进程
int  AfxSuspendTask(int nProcess);
//恢复指定进程
int  AfxResumeTask(int nProcess);
//强置进程时间片用完
void AfxSwapProcess();


DWORD AfxGetDelayMultiplier();
DWORD AfxGetGainMultiplier();

//uS级的Delay函数，入口参数是计数值,采用8253的"1"号定时器
void AfxMicroDelay(WORD wCounter);


//获得时间（多任务版本）
void  FAR GetTime(struct time* pTime);
//获得日期（多任务版本）
void  FAR GetDate(struct date* pDate);
//判断是否有键盘消息（多任务版本）
BOOL  FAR AfxKbhit();
//Delay函数（多任务版本），只有55mS精确度
void KernelDelay(WORD wMilliSeconds);
void KernelDelayForTimer0(WORD wMilliSeconds);
void KernelDelayForTimer1(WORD wMilliSeconds);
void kernelDelayForP61B4(WORD wCX);

void __MultiTaskDelay(WORD wMilliSeconds);

//获得系统计数值
DWORD AfxGetSystemCounter();
//获得BIOS计数值
DWORD AfxGetBiosCounter();

//==============================================
//建立互斥
HANDLE AfxCreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,
	BOOL bInitialOwner, LPCTSTR lpName);
//释放互斥
BOOL AfxReleaseMutex(int hMutex);
//打开命名互斥名柄
HANDLE AfxOpenMutex(DWORD dwDesiredAccess, 
		BOOL bInheritHandle, LPCTSTR lpName);


//==============================================
//建立事件
HANDLE AfxCreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
		BOOL bManualReset,  BOOL bInitialState, LPCTSTR lpName);
//打开命名事件名柄 
HANDLE AfxOpenEvent(DWORD dwDesiredAccess,
		BOOL bInheritHandle, LPCTSTR lpName);
//事件复位(非信号态)
BOOL AfxResetEvent(HANDLE hEvent);
//事件置位(信号态)
BOOL AfxSetEvent(HANDLE hEvent);
//触发相应次数的事件
BOOL AfxPulseEvent(HANDLE hEvent);

//=====================================
//作用建立信号量
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
	LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName);
//释放信号量资源
BOOL ReleaseSemaphore(HANDLE hSemaphore,
	LONG lReleaseCount, LPLONG lpPreviousCount);
//打开命名信号量名柄
HANDLE OpenSemaphore(DWORD dwDesiredAccess, 
		BOOL bInheritHandle, LPCTSTR lpName);

//=====================================
//初始化临界
VOID InitializeCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // address of critical 
                                         // section object
);

//删除临界
VOID DeleteCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // pointer to critical 
                                         // section object
);

//初始化临界并且
BOOL InitializeCriticalSectionAndSpinCount(
  LPCRITICAL_SECTION lpCriticalSection,
                      // pointer to critical section
  DWORD dwSpinCount   // spin count for critical section
);

//偿试进入临界
BOOL TryEnterCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection  // pointer to critical 
                                        // section object
);

//进入临界状态
VOID EnterCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // pointer to critical section object
);

//离开临界状态
VOID LeaveCriticalSection(
  LPCRITICAL_SECTION lpCriticalSection   // address of critical 
                                         // section object
);

//设置临界扇出计数器
DWORD SetCriticalSectionSpinCount(
	LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount);


//=====================================
//关闭同步对象
BOOL AfxCloseSynobject(HANDLE hObject);
//给同步对象加锁
BOOL AfxSynObjectLock(HANDLE hObject);
//给同步对象解锁
BOOL AfxSynObjectUnlock(HANDLE hObect);


void AfxMicroDelayForP61B4(WORD wCX); //15.085uS
int  AfxGetKernelDelayStyle();
void AfxSetKernelDelayStyle(int nStyle);
void KernelDelayForTimer0(WORD wMilliSeconds);
void KernelDelayForTimer1(WORD wMilliSeconds);
void KernelDelayForP61B4(WORD wCX); //15.085uS



#endif



