OSDN Git Service

svn rev.329より移動。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_009 / chnos / timer.c
diff --git a/CHNOSProject/chnos/tolset_chn_000/chnos_009/chnos/timer.c b/CHNOSProject/chnos/tolset_chn_000/chnos_009/chnos/timer.c
new file mode 100644 (file)
index 0000000..312cb36
--- /dev/null
@@ -0,0 +1,190 @@
+\r
+#include "core.h"\r
+\r
+UI_TimerControl timerctrl;\r
+\r
+void Initialise_ProgrammableIntervalTimer(void)\r
+{\r
+       UI_Timer *watch;\r
+\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
+       IO_Out8(PIC0_IMR, IO_In8(PIC0_IMR) & 0xfe);\r
+       timerctrl.count = 0;\r
+       watch = Timer_Get(0, 0);\r
+       watch->timeout = 0xFFFFFFFF;\r
+       watch->count = 0xFFFFFFFF;\r
+       watch->state = inuse;\r
+       timerctrl.next = watch;\r
+       timerctrl.ts = 0;\r
+\r
+       return;\r
+}\r
+\r
+void InterruptHandler20(int *esp)\r
+{\r
+       UI_Timer *tree, *old;\r
+       bool taskswitch;\r
+\r
+       IO_Out8(PIC0_OCW2, 0x60);       /* IRQ-00\8eó\95t\8a®\97¹\82ðPIC\82É\92Ê\92\81B0x60+\94Ô\8d\86\81B*/\r
+       timerctrl.count++;\r
+       taskswitch = false;\r
+\r
+       if(timerctrl.count == timerctrl.next->timeout){ //\8e\9e\8aÔ\82É\82È\82Á\82½\r
+               tree = timerctrl.next;\r
+               timerctrl.next = timerctrl.next->next;\r
+               for(;;){        //\93¯\88ê\83^\83C\83\80\83A\83E\83g\82ð\92T\82·\81B\r
+                       if(tree->fifo != 0){    //FIFO\82Ì\91\97\90M\90æ\82ª\97L\8cø\82©\83`\83F\83b\83N\r
+                               FIFO32_Put(tree->fifo, tree->data);\r
+                       } else if(tree == timerctrl.ts){\r
+                               taskswitch = true;\r
+                       }\r
+                       old = tree;\r
+                       tree = old->tree;\r
+                       old->tree = 0;  //\93¯\88ê\83^\83C\83\80\83A\83E\83g\82È\82µ\r
+                       old->state = configured;        //\90Ý\92è\8dÏ\82Ý\r
+                       if(old->mode == interval){      //\8cJ\82è\95Ô\82·\82È\82ç\r
+                               Timer_Run(old);\r
+                       }\r
+                       if(tree == 0){  //\82à\82¤\93¯\88ê\83^\83C\83\80\83A\83E\83g\82Í\82È\82¢\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       if(taskswitch){\r
+               MultiTask_TaskSwitch();\r
+       }\r
+       return;\r
+}\r
+\r
+uint Timer_Get_Tick(void)\r
+{\r
+       return timerctrl.count;\r
+}\r
+\r
+UI_Timer *Timer_Get(DATA_FIFO *fifo, uint data)\r
+{\r
+       UI_Timer *timer;\r
+\r
+       timer = MemoryBlock_Allocate_System(sizeof(UI_Timer));\r
+       MemoryBlock_Write_Description(timer, "UI_Timer");\r
+\r
+       timer->next = 0;\r
+       timer->tree = 0;\r
+       timer->timeout = 0;\r
+       timer->count = 0;\r
+       timer->fifo = fifo;\r
+       timer->data = data;\r
+       timer->state = initialized;\r
+       return timer;\r
+}\r
+\r
+void Timer_Set(UI_Timer *timer, uint count, timer_mode mode)\r
+{\r
+       timer->count = count;\r
+       timer->mode = mode;\r
+       timer->state = configured;\r
+       return;\r
+}\r
+\r
+void Timer_Run(UI_Timer *timer)\r
+{\r
+       UI_Timer **target;\r
+       uint eflags;\r
+\r
+       if(timer->count == 0){\r
+               return;\r
+       }\r
+\r
+       if(timer->state == inuse){\r
+               return;\r
+       }\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       timer->timeout = timer->count + timerctrl.count;\r
+       target = &timerctrl.next;\r
+       for(;;){\r
+               if((*target)->timeout > timer->timeout){\r
+                       timer->next = *target;  //\8e©\95ª\82Ì\8e\9f\82Ì\83^\83C\83}\81[\82ð\8ew\82·\r
+                       *target = timer;        //\8e©\95ª\82ð\91O\82Ì\83^\83C\83}\81[\82É\98A\8c\8b\r
+                       timer->tree = 0;        //\8e©\95ª\82ªroot\r
+                       timer->state = inuse;   //\93®\8dì\92\86\r
+                       break;\r
+               }\r
+               if((*target)->timeout == timer->timeout){\r
+                       target = &(*target)->tree;\r
+                       for(;;){\r
+                               if(*target == 0){\r
+                                       break;  //\93¯\8e\9e\8d\8f\82Ì\8dÅ\8cã\82ð\92T\82·\r
+                               }\r
+                               target = &(*target)->tree;\r
+                       }\r
+                       timer->next = 0;        //\8fí\82É0\r
+                       *target = timer;//\8e©\95ª\82ð\91O\82Ì\83^\83C\83}\81[\82É\98A\8c\8b\r
+                       timer->tree = 0;        //\8e©\95ª\82ª\8fI\92[\r
+                       timer->state = inuse;   //\93®\8dì\92\86\r
+                       break;\r
+               }\r
+               target = &(*target)->next;\r
+       }\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+void Timer_Cancel(UI_Timer *timer)\r
+{\r
+       UI_Timer **root, **tree;\r
+       uint eflags;\r
+\r
+       eflags = IO_Load_EFlags();\r
+       IO_CLI();\r
+\r
+       root = &timerctrl.next;\r
+\r
+       for(;;){\r
+               if((*root) == 0){       /*\83\8b\81[\83g\82Ì\8fI\92[*/\r
+                       return;\r
+               }\r
+               if((*root) == timer){   /*\83\8b\81[\83g\83^\83C\83}\81[\82ð\83L\83\83\83\93\83Z\83\8b*/\r
+                       if((*root)->tree == 0){ /*\83c\83\8a\81[\82È\82µ*/\r
+                               *root = timer->next;\r
+                       } else{ /*\83c\83\8a\81[\82 \82è*/\r
+                               *root = timer->tree;\r
+                               timer->tree->next = timer->next;\r
+                       }\r
+                       goto cancel;\r
+               } else{\r
+                       tree = &(*root)->tree;\r
+                       for(;;){\r
+                               if((*tree) == 0){       /*\83c\83\8a\81[\82Ì\8fI\92[*/\r
+                                       break;\r
+                               }\r
+                               if((*tree) == timer){   /*\83c\83\8a\81[\83^\83C\83}\81[\82ð\83L\83\83\83\93\83Z\83\8b*/\r
+                                       *tree = timer->tree;\r
+                                       goto cancel;\r
+                               }\r
+                               tree = &(*tree)->tree;\r
+                       }\r
+               }\r
+               root = &(*root)->next;\r
+       }\r
+\r
+cancel:\r
+       timer->next = 0;\r
+       timer->tree = 0;\r
+       timer->timeout = 0;\r
+       timer->state = configured;\r
+\r
+       IO_Store_EFlags(eflags);\r
+       return;\r
+}\r
+\r
+void Timer_TaskSwitch_Set(UI_Timer *ts)\r
+{\r
+       timerctrl.ts = ts;\r
+       return;\r
+}\r