//
// 多任务(协程)预定义
//
#define PT_TICK()           GetTickCount()
#define PT_LINE()           __LINE__

#define PT_CLEAR()          {_pt.line=0; _pt.tick=0;}
#define PT_RESET()          {PT_CLEAR(); return;}

#define PT_WAIT_WHILE(condition)    {_pt.line=PT_LINE(); case PT_LINE(): if(condition) return;}
#define PT_WAIT_UNTIL(condition)    {_pt.line=PT_LINE(); case PT_LINE(): if(!(condition)) return;}
#define PT_YIELD()                  {_pt.line=PT_LINE(); return; case PT_LINE():;}
#define PT_YIELD_WHILE(condition)   {_pt.line=PT_LINE(); return; case PT_LINE(): if(condition) return;}
#define PT_YIELD_UNTIL(condition)   {_pt.line=PT_LINE(); return; case PT_LINE(): if(!(condition)) return;}
#define PT_DELAY_TICK(n)            {_pt.tick=PT_TICK()+(n); PT_YIELD();}
#define PT_DELAY_MS(n)              {_pt.tick=PT_TICK()+MS(n); PT_YIELD();}
#define PT_DELAY_SEC(n)             {_pt.tick=PT_TICK()+SEC(n); PT_YIELD();}
#define MS(n)       (n)
#define SEC(n)      (1000 * (n))

#define delay       PT_DELAY_MS

struct STRU_PT
{
    long tick;
    int line;
};

#define PT_INIT()   \
    static struct STRU_PT _pt;
#define PT_BEGIN()  \
    {\
        if (_pt.tick > 0)\
        {\
            if ((long)(PT_TICK() - _pt.tick) < 0) return;\
            _pt.tick = 0;\
        }\
        switch(_pt.line)\
        {\
            default: break;\
            case 0:;
#define PT_END()    \
        }\
        _pt.line = 0;\
    }

//
// 32位计数器API
//
char _pt_tick0; //Getms比较器
long _pt_tick;  //0.5秒计数器
long GetTickCount()
{
    char ms;
    ms = Getms() - _pt_tick0;
    if (ms >= 128) //超过0.5秒
    {
        _pt_tick0 += ms;
        _pt_tick++;
        ms -= 128;
    }
    return _pt_tick * 500 + (ms * 125 >> 5);
}

// 多任务demo
#if 0
void task1()
{
    static int i;
    PT_INIT()
    PT_BEGIN()
        for (i = 0; i < 10; i++)
        {
            printf("%c, ", 'A' + i);
            PT_DELAY_MS(1000);
        }
    PT_END()
}

void task2()
{
    static int i;
    PT_INIT()
    PT_BEGIN()
        for (i = 0; i < 10; i++)
        {
            printf("%c, ", 'a' + i);
            PT_DELAY_MS(1000);
        }
    PT_END()
}

void main()
{
    long tick;
    for (;;)
    {
        tick = GetTickCount();
	    task0();
        task1();
	    if (tick == GetTickCount())
	    {
	        Delay(4);
	    }
	}
}
#endif
