--- /dev/null
+\r
+#include "core.h"\r
+\r
+UI_TimerControl *timerctrl;\r
+\r
+UI_TimerControl *Initialize_ProgrammableIntervalTimer(void)\r
+{\r
+ timerctrl = (UI_TimerControl *)System_Memory_Allocate(sizeof(UI_TimerControl));\r
+\r
+ timerctrl->tick_10ms = 0;\r
+ timerctrl->TaskSwitch = &Timer_TaskSwitch_Invalid;\r
+\r
+//config watch\r
+ timerctrl->timer_root = Timer_Initialize();\r
+ Timer_Config(timerctrl->timer_root, 0xfffffff, Null, 0, True);\r
+ timerctrl->timer_root->timeout = 0xffffffff;\r
+ timerctrl->timer_root->flags.bit.running = True;\r
+\r
+//config PIT\r
+ IO_Out8(PIT_CTRL, 0x34);\r
+ IO_Out8(PIT_CNT0, 0x9c);\r
+ IO_Out8(PIT_CNT0, 0x2e);\r
+ System_GateDescriptor_Set(0x20, (uint)asm_InterruptHandler20, 0x02, AR_INTGATE32);\r
+ ProgrammableInterruptController_InterruptMask_Clear(0x00);\r
+\r
+ return timerctrl;\r
+}\r
+\r
+void InterruptHandler20(uint *esp)\r
+{\r
+ ProgrammableInterruptController_InterruptRequest_Complete(0x00);\r
+ timerctrl->tick_10ms++;\r
+\r
+ if(timerctrl->timer_root->timeout <= timerctrl->tick_10ms){\r
+ Timer_TimeOut();\r
+ }\r
+\r
+ if((timerctrl->tick_10ms & 0x00000003) == 0){\r
+ timerctrl->TaskSwitch();\r
+ }\r
+\r
+ return;\r
+}\r
+\r
+void Timer_Set_TaskSwitch(void (*TaskSwitchFunction)(void))\r
+{\r
+ if(TaskSwitchFunction != Null){\r
+ timerctrl->TaskSwitch = TaskSwitchFunction;\r
+ } else{\r
+ timerctrl->TaskSwitch = Timer_TaskSwitch_Invalid;\r
+ }\r
+ return;\r
+}\r
+\r
+void Timer_TaskSwitch_Invalid(void)\r
+{\r
+ return;\r
+}\r
+\r
+UI_Timer *Timer_Initialize(void)\r
+{\r
+ UI_Timer *timer;\r
+\r
+ timer = System_Memory_Allocate(sizeof(UI_Timer));\r
+\r
+ timer->flags.bit.initialized = True;\r
+\r
+ #ifdef CHNOSPROJECT_DEBUG_TIMER\r
+ debug("Timer_Initialize:[0x%08X]\n", timer);\r
+ #endif\r
+\r
+ return timer;\r
+}\r
+\r
+uint Timer_Config(UI_Timer *timer, uint tick_ms, DATA_FIFO32 *fifo, uint fifo_putdata, bool interval)\r
+{\r
+ if(timer == Null){\r
+ return 1;\r
+ }\r
+\r
+ if(!timer->flags.bit.initialized){\r
+ return 2;\r
+ }\r
+\r
+ timer->tick = tick_ms / 10;\r
+ timer->fifo = fifo;\r
+ timer->fifo_putdata = fifo_putdata;\r
+ timer->flags.bit.interval = interval;\r
+\r
+ timer->flags.bit.configured = True;\r
+\r
+ return 0;\r
+}\r
+\r
+uint Timer_Run(UI_Timer *timer)\r
+{\r
+ uint eflags;\r
+ UI_Timer **search;\r
+\r
+ if(timer == Null){\r
+ return 1;\r
+ }\r
+\r
+ if(!timer->flags.bit.configured){\r
+ return 2;\r
+ }\r
+\r
+ if(timer->flags.bit.running){\r
+ return 3;\r
+ }\r
+\r
+ timer->timeout = timer->tick + timerctrl->tick_10ms;\r
+ search = &timerctrl->timer_root;\r
+\r
+ eflags = IO_Load_EFlags();\r
+\r
+ for(;;){\r
+ if((*search) == Null){\r
+ #ifdef CHNOSPROJECT_DEBUG_TIMER\r
+ debug("Timer_Run:Invalid link. Abort.\n");\r
+ #endif\r
+ INT_3();\r
+ }\r
+ if((*search)->timeout > timer->timeout){\r
+ IO_CLI();\r
+ timer->root_next = *search;\r
+ *search = timer;\r
+ timer->tree_next = Null;\r
+ timer->flags.bit.running = True;\r
+ break;\r
+ }\r
+ if((*search)->timeout == timer->timeout){\r
+ IO_CLI();\r
+ search = &(*search)->tree_next;\r
+ for(;;){\r
+ if(*search == Null){\r
+ break;\r
+ }\r
+ search = &(*search)->tree_next;\r
+ }\r
+ timer->root_next = Null;\r
+ *search = timer;\r
+ timer->tree_next = Null;\r
+ timer->flags.bit.running = True;\r
+ break;\r
+ }\r
+ search = &(*search)->root_next;\r
+ }\r
+\r
+ IO_Store_EFlags(eflags);\r
+\r
+ return 0;\r
+}\r
+\r
+uint Timer_TimeOut(void)\r
+{\r
+ UI_Timer *search, *old;\r
+\r
+ search = timerctrl->timer_root;\r
+ timerctrl->timer_root = timerctrl->timer_root->root_next;\r
+\r
+ for(;;){\r
+ if(search->fifo != Null){\r
+ FIFO32_Put(search->fifo, search->fifo_putdata);\r
+ }\r
+ old = search;\r
+ search = old->tree_next;\r
+ old->tree_next = 0;\r
+ old->flags.bit.running = False;\r
+ if(old->flags.bit.interval){\r
+ Timer_Run(old);\r
+ }\r
+ if(search == Null){\r
+ break;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+uint Timer_GetTick(void)\r
+{\r
+ return timerctrl->tick_10ms;\r
+}\r
+\r