--- /dev/null
+\r
+#include "core.h"\r
+\r
+UI_TaskControl *taskctrl;\r
+\r
+void Initialise_MultiTask(void)\r
+{\r
+ taskctrl = MemoryBlock_Allocate_System(sizeof(UI_TaskControl));\r
+ MemoryBlock_Write_Description(taskctrl, "SystemTaskCtrl");\r
+\r
+ taskctrl->next = 0;\r
+\r
+ taskctrl->main = MultiTask_Task_Get("SystemMainTask");\r
+ taskctrl->main->tss.ldtr = 0;\r
+ taskctrl->idle->tss.iomap = 0x4000;\r
+ taskctrl->main->tss.cr3 = (uint)ADR_Paging_Directory;\r
+ Load_TR(taskctrl->main->selector << 3);\r
+ taskctrl->now = taskctrl->main;\r
+\r
+ taskctrl->idle = MultiTask_Task_Get("SystemIdleTask");\r
+ taskctrl->idle->tss.ldtr = 0;\r
+ taskctrl->idle->tss.iomap = 0x4000;\r
+ taskctrl->idle->tss.eip = (uint)&MultiTask_IdleTask;\r
+ taskctrl->idle->tss.eflags = 0x00000202;\r
+ taskctrl->idle->tss.esp = (uint)MemoryBlock_Allocate_System(64 * 1024) + 64 * 1024;\r
+ MemoryBlock_Write_Description((void *)(taskctrl->idle->tss.esp - 64 * 1024), "IdleTaskStack");\r
+ taskctrl->idle->tss.es = 1 * 8;\r
+ taskctrl->idle->tss.cs = 2 * 8;\r
+ taskctrl->idle->tss.ss = 1 * 8;\r
+ taskctrl->idle->tss.ds = 1 * 8;\r
+ taskctrl->idle->tss.fs = 1 * 8;\r
+ taskctrl->idle->tss.gs = 1 * 8;\r
+ taskctrl->idle->tss.cr3 = (uint)ADR_Paging_Directory;\r
+\r
+ MultiTask_Task_Run(taskctrl->idle);\r
+ MultiTask_Task_Run(taskctrl->main);\r
+\r
+ taskctrl->ts = Timer_Get(0, 0);\r
+ Timer_Set(taskctrl->ts, 2, once);\r
+ Timer_TaskSwitch_Set(taskctrl->ts);\r
+ Timer_Run(taskctrl->ts);\r
+\r
+ return;\r
+}\r
+\r
+UI_Task *MultiTask_Task_Get(const uchar *description)\r
+{\r
+ uint i;\r
+ UI_Task *task;\r
+\r
+ task = MemoryBlock_Allocate_System(sizeof(UI_Task));\r
+ MemoryBlock_Write_Description(task, "UI_Task");\r
+\r
+ task->tss.backlink = 0;\r
+ task->tss.reserve00 = 0;\r
+ task->tss.esp0 = 0;\r
+ task->tss.ss0 = 0;\r
+ task->tss.reserve01 = 0;\r
+ task->tss.esp1 = 0;\r
+ task->tss.ss1 = 0;\r
+ task->tss.reserve02 = 0;\r
+ task->tss.esp2 = 0;\r
+ task->tss.ss2 = 0;\r
+ task->tss.reserve03 = 0;\r
+ task->tss.cr3 = 0;\r
+ task->tss.eip = 0;\r
+ task->tss.eflags = 0;\r
+ task->tss.eax = 0;\r
+ task->tss.ecx = 0;\r
+ task->tss.edx = 0;\r
+ task->tss.ebx = 0;\r
+ task->tss.esp = 0;\r
+ task->tss.ebp = 0;\r
+ task->tss.esi = 0;\r
+ task->tss.edi = 0;\r
+ task->tss.es = 0;\r
+ task->tss.reserve04 = 0;\r
+ task->tss.cs = 0;\r
+ task->tss.reserve05 = 0;\r
+ task->tss.ss = 0;\r
+ task->tss.reserve06 = 0;\r
+ task->tss.ds = 0;\r
+ task->tss.reserve07 = 0;\r
+ task->tss.fs = 0;\r
+ task->tss.reserve08 = 0;\r
+ task->tss.gs = 0;\r
+ task->tss.reserve09 = 0;\r
+ task->tss.ldtr = 0;\r
+ task->tss.reserve10 = 0;\r
+ task->tss.flags = 0;\r
+ task->tss.iomap = 0;\r
+\r
+ task->selector = System_SegmentDescriptor_Set(sizeof(IO_TaskStatusSegment) - 1, (int)&task->tss, AR_TSS32);\r
+\r
+ task->quantum = 2; /*0.02sec Default*/\r
+\r
+ task->cputime = 0;\r
+\r
+ task->state = initialized;\r
+\r
+ task->cons = 0;\r
+\r
+ for(i = 0; i < (TASK_DESCRIPTION_LENGTH - 1); i++){\r
+ if(description[i] == 0x00){\r
+ break;\r
+ }\r
+ task->description[i] = description[i];\r
+ }\r
+ task->description[i] = 0x00;\r
+ return task;\r
+}\r
+\r
+void MultiTask_Task_Change_Quantum(UI_Task *task, uint quantum)\r
+{\r
+ if(1 <= quantum && quantum <= 25){ /*0.01-0.25sec*/\r
+ task->quantum = quantum;\r
+ }\r
+ return;\r
+}\r
+\r
+void MultiTask_Task_Run(UI_Task *task)\r
+{\r
+ uint eflags;\r
+\r
+ if(!(1 <= task->quantum && task->quantum <= 25)){\r
+ task->quantum = 2;\r
+ }\r
+ if(task->state == inuse){\r
+ return;\r
+ } else if(task->state == configured){\r
+ task->state = inuse;\r
+ return;\r
+ }\r
+ eflags = IO_Load_EFlags();\r
+ IO_CLI();\r
+\r
+ task->next = taskctrl->next;\r
+ taskctrl->next = task;\r
+ task->state = inuse;\r
+\r
+ IO_Store_EFlags(eflags);\r
+ return;\r
+}\r
+\r
+void MultiTask_Task_Sleep(UI_Task *task)\r
+{\r
+ uint eflags;\r
+\r
+ eflags = IO_Load_EFlags();\r
+ IO_CLI();\r
+\r
+ task->state = configured;\r
+ if(taskctrl->now == task){\r
+ Timer_Cancel(taskctrl->ts);\r
+ MultiTask_TaskSwitch();\r
+ }\r
+\r
+ IO_Store_EFlags(eflags);\r
+\r
+ return;\r
+}\r
+\r
+void MultiTask_Task_Remove(UI_Task *task)\r
+{\r
+ UI_Task **next, *newnow;\r
+ uint eflags;\r
+ bool ts;\r
+\r
+ ts = false;\r
+\r
+ eflags = IO_Load_EFlags();\r
+ IO_CLI();\r
+\r
+ if(taskctrl->now == task){\r
+ ts = true;\r
+ }\r
+\r
+ for(newnow = taskctrl->next; newnow->next != 0; newnow = newnow->next){\r
+\r
+ }\r
+\r
+ for(next = &taskctrl->next; (*next)->next != 0; next = &(*next)->next){\r
+ if((*next) == task){\r
+ (*next) = task->next;\r
+ task->next = 0;\r
+ task->state = initialized;\r
+ break;\r
+ }\r
+ newnow = (*next);\r
+ }\r
+ if(ts){\r
+ taskctrl->now = newnow;\r
+ MultiTask_TaskSwitch();\r
+ }\r
+ IO_Store_EFlags(eflags);\r
+ return;\r
+}\r
+\r
+void MultiTask_Task_Arguments(UI_Task *task, int args, ...)\r
+{\r
+ int i;\r
+ va_list ap;\r
+\r
+ va_start(ap, args);\r
+ \r
+ task->tss.esp -= 4 * (args + 1);\r
+\r
+ for(i = 1; i < args + 1; i++){\r
+ *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);\r
+ }\r
+ va_end(ap);\r
+ return; \r
+}\r
+\r
+void MultiTask_TaskSwitch(void)\r
+{\r
+ UI_Task *old, *new;\r
+ uint eflags;\r
+\r
+ eflags = IO_Load_EFlags();\r
+ IO_CLI();\r
+\r
+ old = taskctrl->now;\r
+\r
+ for(new = taskctrl->now->next; ; new = new->next){\r
+ if(new == 0){\r
+ new = taskctrl->next;\r
+ }\r
+ if(new->state == inuse){ /*configured = sleep*/\r
+ taskctrl->now = new;\r
+ break;\r
+ }\r
+ }\r
+ if(old == taskctrl->now){\r
+ taskctrl->now = old;\r
+ old = 0;\r
+ }\r
+ Timer_Set(taskctrl->ts, taskctrl->now->quantum, once);\r
+ Timer_Run(taskctrl->ts);\r
+ taskctrl->now->cputime += taskctrl->now->quantum;\r
+ if(old){\r
+ FarJMP(0, taskctrl->now->selector << 3);\r
+ }\r
+ IO_Store_EFlags(eflags);\r
+ return;\r
+}\r
+\r
+UI_Task *MultiTask_Get_NowTask(void)\r
+{\r
+ return taskctrl->now;\r
+}\r
+\r
+void MultiTask_IdleTask(void)\r
+{\r
+ for(;;){\r
+ IO_HLT();\r
+ }\r
+}\r