-
Notifications
You must be signed in to change notification settings - Fork 1
/
crt0.c
87 lines (73 loc) · 1.85 KB
/
crt0.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Entry point for C runtime initilization code
*
* This will set initial values for data memory and otherwise create
* the conditions needed for the C environment */
extern int main(void);
#ifdef __cplusplus
extern "C"
#endif
void _start2(void)
{
/* Fill .data section with initial values */
{
extern char __VAL_START;
extern char __DATA_START;
extern char __DATA_END;
char *src = &__VAL_START;
char *dst = &__DATA_START;
while(dst < &__DATA_END)
{
*dst++ = *src++;
}
}
/* Erase .bss section */
{
extern char __BSS_START;
extern char __BSS_END;
char *dst = &__BSS_START;
while(dst < &__BSS_END)
{
*dst++ = 0;
}
}
#ifdef __cplusplus
/* Call all initial constructors.
* The .ctors section is filled with function pointers to constructors.
* Iterate through them and call each function. */
{
extern int __CTOR_START;
extern int __CTOR_END;
typedef void(*funcptr)(void);
funcptr *ctor = (funcptr*)&__CTOR_START;
while(ctor < (funcptr*)&__CTOR_END)
{
(*(ctor++))();
}
}
#endif
/* Start running C code */
main();
/* We cannot properly handle a return from C code.
* Instead, just spin here until the console is reset */
while(1);
}
#ifdef __cplusplus
extern "C"
#endif
void _start(void)
{
/* Disable interrupts
*
* This will disable console reset via keyboard, music playback,
* sprite automotion, etc. But will make the environment much simpler
* to work in. Users can re-enable interrupts later if they wish. */
asm("\tlimi 0");
/* Set initial workspace
*
* The registers will be located at the start of scratchpad memory */
asm("\tlwpi >8300");
/* Create the stack before declaring any variables */
asm("\tli sp, >8400");
/* Call the second part directly to prevent a stack for this function */
asm("\tjmp _start2");
}