Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / arch / all-mingw32 / exec / exec_init.c
blob83379de8a5a93e405e29c48cc27bdb3b12dea46f
1 /*
2 Copyright 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: exec.library resident and initialization.
6 Lang: english
7 */
8 #define DEBUG 0
10 #include <exec/types.h>
11 #include <exec/lists.h>
12 #include <exec/execbase.h>
13 #include <exec/interrupts.h>
14 #include <exec/resident.h>
15 #include <exec/memory.h>
16 #include <exec/alerts.h>
17 #include <exec/tasks.h>
18 #include <hardware/intbits.h>
19 #include <hardware/custom.h>
20 #include <dos/dosextens.h>
22 #include <aros/system.h>
23 #include <aros/arossupportbase.h>
24 #include <aros/asmcall.h>
25 #include <aros/config.h>
27 #include <aros/debug.h>
29 #include <proto/arossupport.h>
30 #include <proto/exec.h>
31 #include <proto/kernel.h>
32 #include <clib/macros.h> /* need ABS() */
34 #include "exec_intern.h"
35 #include "exec_util.h"
36 #include "etask.h"
37 #include LC_LIBDEFS_FILE
39 static const UBYTE name[];
40 static const UBYTE version[];
41 extern const char LIBEND;
42 struct ExecBase *GM_UNIQUENAME(init)();
44 const struct Resident Exec_resident =
46 RTC_MATCHWORD,
47 (struct Resident *)&Exec_resident,
48 (APTR)&LIBEND,
49 RTF_SINGLETASK,
50 VERSION_NUMBER,
51 NT_LIBRARY,
52 105,
53 (STRPTR)name,
54 (STRPTR)&version[6],
55 &GM_UNIQUENAME(init)
58 static const UBYTE name[] = MOD_NAME_STRING;
59 static const UBYTE version[] = VERSION_STRING;
61 extern void debugmem(void);
63 /**************** GLOBAL SYSBASE ***************/
64 struct ExecBase * SysBase = NULL;
67 We temporarily redefine kprintf() so we use the real version in case
68 we have one of these two fn's called before AROSSupportBase is ready.
71 #undef kprintf
72 #undef rkprintf
73 #undef vkprintf
74 struct Library * PrepareAROSSupportBase (struct ExecBase * SysBase)
76 struct AROSSupportBase * AROSSupportBase;
77 AROSSupportBase = AllocMem(sizeof(struct AROSSupportBase), MEMF_CLEAR);
78 AROSSupportBase->kprintf = (void *)kprintf;
79 AROSSupportBase->rkprintf = (void *)rkprintf;
80 AROSSupportBase->vkprintf = (void *)vkprintf;
81 NEWLIST(&AROSSupportBase->AllocMemList);
83 #warning FIXME Add code to read in the debug options
85 return (struct Library *)AROSSupportBase;
88 void _aros_not_implemented(char *X)
90 kprintf("Unsupported function at offset -0x%h in %s\n",
91 ABS(*(WORD *)((&X)[-1]-2)),
92 ((struct Library *)(&X)[-2])->lib_Node.ln_Name);
94 #define kprintf (((struct AROSSupportBase *)(SysBase->DebugAROSBase))->kprintf)
95 #define rkprintf (((struct AROSSupportBase *)(SysBase->DebugAROSBase))->rkprintf)
96 #define vkprintf (((struct AROSSupportBase *)(SysBase->DebugAROSBase))->vkprintf)
98 /* IntServer:
99 This interrupt handler will send an interrupt to a series of queued
100 interrupt servers. Servers should return D0 != 0 (Z clear) if they
101 believe the interrupt was for them, and no further interrupts will
102 be called. This will only check the value in D0 for non-m68k systems,
103 however it SHOULD check the Z-flag on 68k systems.
105 Hmm, in that case I would have to separate it from this file in order
106 to replace it...
108 AROS_UFH5S(void, IntServer,
109 AROS_UFHA(ULONG, intMask, D0),
110 AROS_UFHA(struct Custom *, custom, A0),
111 AROS_UFHA(struct List *, intList, A1),
112 AROS_UFHA(APTR, intCode, A5),
113 AROS_UFHA(struct ExecBase *, SysBase, A6))
115 AROS_USERFUNC_INIT
117 struct Interrupt * irq;
119 ForeachNode(intList, irq)
121 if( AROS_UFC4(int, irq->is_Code,
122 AROS_UFCA(struct Custom *, custom, A0),
123 AROS_UFCA(APTR, irq->is_Data, A1),
124 AROS_UFCA(APTR, irq->is_Code, A5),
125 AROS_UFCA(struct ExecBase *, SysBase, A6)
127 break;
130 AROS_USERFUNC_EXIT
133 void VBlankHandler(struct ExecBase *SysBase, void *dummy)
135 struct IntVector *iv = &SysBase->IntVects[INTB_VERTB];
137 /* First decrease Elapsed time for current task */
138 if (SysBase->Elapsed && (--SysBase->Elapsed == 0))
140 SysBase->SysFlags |= 0x2000;
141 SysBase->AttnResched |= ARF_AttnSwitch;
144 /* If the VBlank vector in SysBase is set, call it. */
145 if (iv->iv_Code)
147 AROS_UFC5(void, iv->iv_Code,
148 AROS_UFCA(ULONG, 0, D1),
149 AROS_UFCA(ULONG, 0, A0),
150 AROS_UFCA(APTR, iv->iv_Data, A1),
151 AROS_UFCA(APTR, iv->iv_Code, A5),
152 AROS_UFCA(struct ExecBase *, SysBase, A6)
157 extern ULONG SoftIntDispatch();
159 AROS_UFH3(LIBBASETYPEPTR, GM_UNIQUENAME(init),
160 AROS_UFHA(ULONG, dummy, D0),
161 AROS_UFHA(BPTR, segList, A0),
162 AROS_UFHA(struct ExecBase *, sysBase, A6)
165 AROS_USERFUNC_INIT
167 D(bug("[exec_init] Entered exec.library init\n"));
168 SysBase = sysBase;
170 Create boot task. Sigh, we actually create a Process sized Task,
171 since DOS needs to call things which think it has a Process and
172 we don't want to overwrite memory with something strange do we?
174 We do this until at least we can boot dos more cleanly.
177 struct Task *t;
178 struct MemList *ml;
180 ml = (struct MemList *)AllocMem(sizeof(struct MemList), MEMF_PUBLIC|MEMF_CLEAR);
181 t = (struct Task *) AllocMem(sizeof(struct Process), MEMF_PUBLIC|MEMF_CLEAR);
183 if( !ml || !t )
185 kprintf("ERROR: Cannot create Boot Task!\n");
186 Alert( AT_DeadEnd | AG_NoMemory | AN_ExecLib );
188 ml->ml_NumEntries = 1;
189 ml->ml_ME[0].me_Addr = t;
190 ml->ml_ME[0].me_Length = sizeof(struct Process);
192 NEWLIST(&t->tc_MemEntry);
193 NEWLIST(&((struct Process *)t)->pr_MsgPort.mp_MsgList);
195 /* It's the boot process that RunCommand()s the boot shell, so we
196 must have this list initialized */
197 NEWLIST((struct List *)&((struct Process *)t)->pr_LocalVars);
199 AddHead(&t->tc_MemEntry,&ml->ml_Node);
201 t->tc_Node.ln_Name = "Boot Task";
202 t->tc_Node.ln_Pri = 0;
203 t->tc_State = TS_RUN;
204 t->tc_SigAlloc = 0xFFFF;
205 t->tc_SPLower = 0; /* This is the system's stack */
206 t->tc_SPUpper = (APTR)~0UL;
207 t->tc_Flags |= TF_ETASK;
209 t->tc_UnionETask.tc_ETask = AllocVec
211 sizeof(struct IntETask),
212 MEMF_ANY|MEMF_CLEAR
215 if (!t->tc_UnionETask.tc_ETask)
217 kprintf("Not enough memory for first task\n");
218 Alert( AT_DeadEnd | AG_NoMemory | AN_ExecLib );
221 /* Initialise the ETask data. */
222 InitETask(t, t->tc_UnionETask.tc_ETask);
224 GetIntETask(t)->iet_Context = KrnCreateContext();
225 if (!GetIntETask(t)->iet_Context)
227 kprintf("Not enough memory for first task\n");
228 Alert( AT_DeadEnd | AG_NoMemory | AN_ExecLib );
231 sysBase->ThisTask = t;
232 sysBase->Elapsed = sysBase->Quantum;
235 /* Install the interrupt servers */
236 int i;
237 for(i=0; i < 16; i++)
238 if( (1<<i) & (INTF_PORTS|INTF_COPER|INTF_VERTB|INTF_EXTER|INTF_SETCLR))
240 struct Interrupt *is;
241 struct SoftIntList *sil;
242 is = AllocMem(sizeof(struct Interrupt) + sizeof(struct SoftIntList),
243 MEMF_CLEAR|MEMF_PUBLIC);
244 if( is == NULL )
246 kprintf("ERROR: Cannot install Interrupt Servers!\n");
247 Alert( AT_DeadEnd | AN_IntrMem );
249 sil = (struct SoftIntList *)((struct Interrupt *)is + 1);
251 is->is_Code = &IntServer;
252 is->is_Data = sil;
253 NEWLIST((struct List *)sil);
254 SetIntVector(i,is);
256 else
258 struct Interrupt * is;
259 switch(i)
261 case INTB_SOFTINT:
262 is = AllocMem(sizeof(struct Interrupt), MEMF_CLEAR|MEMF_PUBLIC);
263 if (NULL == is)
265 kprintf("Error: Cannot install Interrupt Handler!\n");
266 Alert( AT_DeadEnd | AN_IntrMem );
268 is->is_Node.ln_Type = NT_INTERRUPT;
269 is->is_Node.ln_Pri = 0;
270 is->is_Node.ln_Name = "SW Interrupt Dispatcher";
271 is->is_Data = NULL;
272 is->is_Code = (void *)SoftIntDispatch;
273 SetIntVector(i,is);
274 break;
278 /* Install the VBlank handler. We drop the handle because exec.library never expunges. */
279 KrnAddIRQHandler(0, VBlankHandler, sysBase, NULL);
281 /* We now start up the interrupts */
282 Permit();
283 Enable();
285 D(debugmem());
287 /* This will cause everything else to run. This call will not return.
288 This is because it eventually falls into strap, which will call
289 the bootcode, which itself is not supposed to return. It is up
290 to the DOS (whatever it is) to Permit(); RemTask(NULL);
292 InitCode(RTF_COLDSTART, 0);
294 /* There had better be some kind of task waiting to run. */
295 return NULL;
296 AROS_USERFUNC_EXIT
299 #ifdef sysBase
300 #undef sysBase
301 #endif
303 AROS_PLH1(struct ExecBase *, open,
304 AROS_LHA(ULONG, version, D0),
305 struct ExecBase *, SysBase, 1, Exec)
307 AROS_LIBFUNC_INIT
309 /* I have one more opener. */
310 SysBase->LibNode.lib_OpenCnt++;
311 return SysBase;
312 AROS_LIBFUNC_EXIT
315 AROS_PLH0(BPTR, close,
316 struct ExecBase *, SysBase, 2, Exec)
318 AROS_LIBFUNC_INIT
320 /* I have one fewer opener. */
321 SysBase->LibNode.lib_OpenCnt--;
322 return 0;
323 AROS_LIBFUNC_EXIT