4 //FIFO
\82É
\82æ
\82é
\83^
\83X
\83N
\82Ì
\8e©
\93®
\8bN
\93®
\82Í
\8aù
\92è
\82Å
\97L
\8cø
\82Å
\82·
\82ª
\81A
\83^
\83X
\83N
\82ª
\96¾
\8e¦
\93I
\82É
\8eÀ
\8ds
\82³
\82ê
\82é
\82Ü
\82Å
\82Í
\96³
\8cø
\82É
\82È
\82Á
\82Ä
\82¢
\82Ü
\82·
\81B
\r
5 //
\83^
\83X
\83N
\82ÍSTI
\89º
\82Å
\8aJ
\8en
\82³
\82ê
\82Ü
\82·
\81i
\8aO
\95\94\8a\84\82è
\8d\9e\82Ý
\97L
\8cø
\81j
\81B
\r
7 UI_TaskControl *Initialize_MultiTask_Control(IO_MemoryControl sysmemctrl)
\r
9 UI_TaskControl *ctrl;
\r
12 ctrl = Memory_Allocate(sysmemctrl, sizeof(UI_TaskControl));
\r
14 ctrl->sysmemctrl = sysmemctrl;
\r
16 maintask = MultiTask_Task_Initialize(ctrl, 0);
\r
18 Load_TR(maintask->selector << 3);
\r
20 ctrl->start = maintask;
\r
21 ctrl->now = maintask;
\r
23 maintask->flags.linked = True;
\r
24 maintask->flags.running = True;
\r
25 maintask->flags.first_run = False;
\r
26 FIFO32_Set_Task(maintask->fifo, maintask);
\r
31 UI_Task *MultiTask_Task_Initialize(UI_TaskControl *ctrl, uint tss_additional_size)
\r
35 task = Memory_Allocate(ctrl->sysmemctrl, sizeof(UI_Task));
\r
36 task->tss = Memory_Allocate(ctrl->sysmemctrl, sizeof(CPU_TaskStateSegment) + tss_additional_size);
\r
38 task->tss->reserve00 = 0;
\r
39 task->tss->reserve01 = 0;
\r
40 task->tss->reserve02 = 0;
\r
41 task->tss->reserve03 = 0;
\r
42 task->tss->reserve04 = 0;
\r
43 task->tss->reserve05 = 0;
\r
44 task->tss->reserve06 = 0;
\r
45 task->tss->reserve07 = 0;
\r
46 task->tss->reserve08 = 0;
\r
47 task->tss->reserve09 = 0;
\r
48 task->tss->reserve10 = 0;
\r
49 task->tss->reserve11 = 0;
\r
51 task->tss->backlink = 0;
\r
52 task->tss->esp0 = 0;
\r
54 task->tss->esp1 = 0;
\r
56 task->tss->esp2 = 0;
\r
61 task->tss->eflags.eflags = 0x00000202; //bit1=True, IF=True
\r
79 task->tss->ldtr = 0;
\r
80 task->tss->flag_trap = False;
\r
81 task->tss->iomap_base = 0x00004000; //TSS
\83\8a\83~
\83b
\83g
\88È
\8fã
\82È
\82ç
\96³
\8cø
\r
83 task->selector = System_SegmentDescriptor_Set(sizeof(CPU_TaskStateSegment) + tss_additional_size - 1, (uint)task->tss, AR_TSS32);
\r
88 task->fifo = FIFO32_Initialize(ctrl->sysmemctrl, TASK_FIFOSIZE);
\r
90 task->flags.initialized = True;
\r
91 task->flags.linked = False;
\r
92 task->flags.first_run = True;
\r
97 uint MultiTask_Internal_Task_SetLink(UI_TaskControl *ctrl, UI_Task *task)
\r
102 eflags = IO_Load_EFlags();
\r
105 for(last = &ctrl->start; *last != Null; last = &(*last)->next){
\r
107 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
108 debug("MultiTask_Internal_Task_SetLink:Task has already been linked(sel:0x%X).\n", task->selector);
\r
115 task->flags.linked = True;
\r
117 IO_Store_EFlags(eflags);
\r
122 uint MultiTask_Internal_Task_ClearLink(UI_TaskControl *ctrl, UI_Task *task)
\r
127 eflags = IO_Load_EFlags();
\r
130 for(find = &ctrl->start; *find != task; find = &(*find)->next){
\r
132 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
133 debug("MultiTask_Internal_Task_ClearLink:Task not found(sel:0x%X).\n", task->selector);
\r
138 *find = task->next;
\r
140 task->flags.linked = False;
\r
141 task->flags.running = False;
\r
143 if(ctrl->now == task){
\r
144 MultiTask_TaskSwitch(ctrl);
\r
147 IO_Store_EFlags(eflags);
\r
152 void MultiTask_Task_Run(UI_TaskControl *ctrl, UI_Task *task)
\r
154 #ifdef CHNOSPROJECT_DEBUG_CALLLINK
\r
155 debug("MultiTask_Task_Run:Called from[0x%08X].\n", *((uint *)(&ctrl - 1)));
\r
158 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
159 debug("MultiTask_Task_Run:Start Running Rq(sel:0x%X).\n", task->selector);
\r
162 if(task->flags.running){
\r
163 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
164 debug("MultiTask_Task_Run:Task has already been running(sel:0x%X).\n", task->selector);
\r
169 if(!task->flags.linked){
\r
170 MultiTask_Internal_Task_SetLink(ctrl, task);
\r
173 task->flags.running = True;
\r
175 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
176 debug("MultiTask_Task_Run:Start Running(sel:0x%X).\n", task->selector);
\r
179 if(task->flags.first_run){
\r
180 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
181 debug("MultiTask_Task_Run:FIFO task autorun is enabled.\n");
\r
183 FIFO32_Set_Task(task->fifo, task);
\r
184 task->flags.first_run = False;
\r
190 void MultiTask_TaskSwitch(UI_TaskControl *ctrl)
\r
195 eflags = IO_Load_EFlags();
\r
198 for(nexttask = ctrl->now->next; ; nexttask = nexttask->next){
\r
199 if(nexttask == Null){ //
\83\8a\83\93\83N
\8fI
\92[
\82É
\97\88\82½
\82ç
\90æ
\93ª
\82Ö
\8aª
\82«
\96ß
\82·
\r
200 nexttask = ctrl->start;
\r
202 if(nexttask == ctrl->now){ //
\8eÀ
\8ds
\92\86\8fó
\91Ô
\82Ì
\83^
\83X
\83N
\82Í
\8c»
\8dÝ
\8eÀ
\8ds
\92\86\82Ì
\82±
\82Ì
\83^
\83X
\83N
\82µ
\82©
\82È
\82¢
\82Ì
\82Å
\83^
\83X
\83N
\83X
\83C
\83b
\83`
\82È
\82µ
\r
205 if(nexttask->flags.running){ //
\8eÀ
\8ds
\92\86\8fó
\91Ô
\82Ì
\82Ù
\82©
\82Ì
\83^
\83X
\83N
\82ª
\8c©
\82Â
\82©
\82Á
\82½
\82Ì
\82Å
\83^
\83X
\83N
\83X
\83C
\83b
\83`
\r
206 ctrl->now = nexttask;
\r
207 ctrl->now->count++;
\r
208 FarJMP(0, ctrl->now->selector << 3);
\r
213 IO_Store_EFlags(eflags);
\r
218 void MultiTask_Task_Sleep(UI_TaskControl *ctrl, UI_Task *task)
\r
220 //CPL=0
\89º
\82ð
\91z
\92è
\r
224 if(task == ctrl->now && task == ctrl->start){ //
\8e©
\95ª
\82ª
\97B
\88ê
\96³
\93ñ
\82Ì
\83^
\83X
\83N
\82¾
\82Á
\82½
\8fê
\8d\87\81A
\83X
\83\8a\81[
\83v
\82Í
\8eÀ
\8ds
\82Å
\82«
\82È
\82¢
\82Ì
\82ÅHLT
\82·
\82é
\r
225 eflags = IO_Load_EFlags();
\r
227 IO_Store_EFlags(eflags);
\r
231 task->flags.running = False;
\r
233 if(ctrl->now == task){
\r
234 MultiTask_TaskSwitch(ctrl);
\r
240 void MultiTask_Task_Kill(UI_TaskControl *ctrl, UI_Task *task)
\r
242 //CPL=0
\89º
\82ð
\91z
\92è
\r
244 if(task == ctrl->now && task == ctrl->start){ //
\8e©
\95ª
\82ª
\97B
\88ê
\96³
\93ñ
\82Ì
\83^
\83X
\83N
\82¾
\82Á
\82½
\8fê
\8d\87\81Akill
\82ÍOS
\8e©
\91Ì
\82Ì
\8fI
\97¹
\82ð
\88Ó
\96¡
\82·
\82é
\82Ì
\82Å
\81A
\83A
\83{
\81[
\83g
\r
245 #ifdef CHNOSPROJECT_DEBUG_MULTITASK
\r
246 debug("MultiTask_Task_Stop:Attempted to stop last task. Abort.\n");
\r
252 MultiTask_Internal_Task_ClearLink(ctrl, task);
\r
257 void MultiTask_Task_Free(UI_TaskControl *ctrl, UI_Task *task)
\r
259 if(task->flags.linked){
\r
260 MultiTask_Task_Kill(ctrl, task);
\r
265 UI_Task *MultiTask_GetNowTask(UI_TaskControl *ctrl)
\r
270 uint MultiTask_Push_Arguments(UI_Task *task, uint args, ...)
\r
275 vargs = (uint *)(&args + 1);
\r
277 task->tss->esp -= 4 * (args + 1);
\r
279 for(i = 1; i < args + 1; i++){
\r
280 *((uint *)(task->tss->esp + (i * 4))) = vargs[i - 1];
\r