Big up for Volca ... slowdown the busy icon
[open-ps2-loader.git] / elfldr / crt0.s
blob2be0ae478d14f12caab95864abe817092e14a3cd
1 # Copyright 2009-2010, Ifcaro, jimmikaelkael & Polo
2 # Copyright 2006-2008 Polo
3 # Licenced under Academic Free License version 3.0
4 # Review OPNPS2LD README & LICENSE files for further details.
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # Modified crt0.s
11 # Remove _ps2sdk_args_parse, _ps2sdk_libc_init and _ps2sdk_libc_deinit weak functions for size optimization
13 .weak _init
14 .type _init, @function
16 .weak _fini
17 .type _fini, @function
19 .extern _heap_size
20 .extern _stack
21 .extern _stack_size
23 .set noat
24 .set noreorder
26 .text
27 .align 2
29 nop
30 nop
32 .globl _start
33 .ent _start
34 _start:
36 zerobss:
37 # clear bss area
39 la $2, _fbss
40 la $3, _end
43 sltu $1, $2, $3
44 beq $1, $0, 2f
45 nop
46 sq $0, ($2)
47 addiu $2, $2, 16
48 j 1b
49 nop
52 # store eventual loader arguments (passed via a0)
54 la $2, _loader_args
55 sw $4, ($2)
57 setupthread:
58 # setup current thread
60 la $4, _gp
61 la $5, _stack
62 la $6, _stack_size
63 la $7, _args
64 la $8, _root
65 move $gp, $4
66 addiu $3, $0, 60
67 syscall # SetupThread(_gp, _stack, _stack_size, _args, _root)
68 move $sp, $2
70 # initialize heap
72 la $4, _end
73 la $5, _heap_size
74 addiu $3, $0, 61
75 syscall # SetupHeap(_end, _heap_size)
77 # writeback data cache
79 move $4, $0
80 addiu $3, $0, 100
81 syscall # FlushCache(0)
83 ctors:
84 # call global constructors (weak)
86 la $8, _init
87 beqz $8, 1f
88 nop
89 jalr $8 # _init()
90 nop
93 # call main
96 jal _getargs
97 nop
98 jal main # main(argc, argv)
99 nop
101 # call _exit
103 j _exit # _exit(retval)
104 move $4, $2
105 .end _start
107 .align 3
109 .globl _exit
110 .ent _exit
111 .text
112 _exit:
113 la $2, _retval
114 sw $4, ($2)
116 dtors:
117 # call global destructors (weak)
119 la $8, _fini
120 beqz $8, 1f
122 jalr $8 # _fini()
126 # conditional exit (depending on if we got arguments through the loader or not)
128 la $2, _retval
129 lw $4, ($2)
131 la $5, _loader_args
132 lw $6, ($5)
133 beqz $6, 1f
136 # called from a loader, close thread
138 lw $7, ($6)
139 sw $0, ($7) # clear thread id
141 addiu $3, $0, 36
142 syscall # ExitDeleteThread() (noreturn)
145 # not called from a loader, return to browser
147 addiu $3, $0, 4
148 syscall # Exit(retval) (noreturn)
150 .end _exit
152 .ent _root
153 _root:
154 addiu $3, $0, 35
155 syscall # ExitThread() (noreturn)
156 .end _root
158 .ent _getargs
159 _getargs:
160 # check normal arguments
162 la $2, _args
163 lw $3, ($2)
164 bnez $3, 1f
167 # check for arguments passed by a loader
169 la $2, _loader_args
170 lw $3, ($2)
171 beqzl $3, 2f
172 addu $4, $0, 0
174 addiu $2, $3, 4
176 lw $4, ($2)
177 addiu $5, $2, 4
179 jr $ra # $4 = argc, $5 = argv
181 .end _getargs
183 .bss
184 .align 6
185 _args:
186 .space 4+16*4+256 # argc, 16 arguments, 256 bytes payload
187 _loader_args:
188 .space 4 # pointer to loader arguments: thread id, argc, argv
189 _retval:
190 .space 4